commit:     3b64f761680a7e83f6fc64e90aab9c0923e1cff6
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 11 18:19:36 2018 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Jul 11 18:19:36 2018 +0000
URL:        https://gitweb.gentoo.org/proj/blogs-gentoo.git/commit/?id=3b64f761

Initial commit google-authenticator

 plugins/google-authenticator/base32.php            |  82 +++
 .../google-authenticator/google-authenticator.php  | 549 +++++++++++++++++++++
 plugins/google-authenticator/jquery.qrcode.min.js  |  28 ++
 .../lang/google-authenticator-da_DK.mo             | Bin 0 -> 2736 bytes
 .../lang/google-authenticator-da_DK.po             | 113 +++++
 .../lang/google-authenticator-de_DE.mo             | Bin 0 -> 2565 bytes
 .../lang/google-authenticator-de_DE.po             | 119 +++++
 .../lang/google-authenticator-es_ES.mo             | Bin 0 -> 2749 bytes
 .../lang/google-authenticator-es_ES.po             | 131 +++++
 .../lang/google-authenticator-fr_FR.mo             | Bin 0 -> 2635 bytes
 .../lang/google-authenticator-fr_FR.po             | 133 +++++
 .../lang/google-authenticator-it_IT.mo             | Bin 0 -> 3324 bytes
 .../lang/google-authenticator-it_IT.po             | 143 ++++++
 .../lang/google-authenticator-zh_CN.mo             | Bin 0 -> 3026 bytes
 .../lang/google-authenticator-zh_CN.po             | 126 +++++
 .../lang/google-authenticator.pot                  | 112 +++++
 plugins/google-authenticator/readme.txt            | 170 +++++++
 plugins/google-authenticator/screenshot-1.jpg      | Bin 0 -> 28821 bytes
 plugins/google-authenticator/screenshot-2.jpg      | Bin 0 -> 101559 bytes
 plugins/google-authenticator/screenshot-3.jpg      | Bin 0 -> 148800 bytes
 plugins/google-authenticator/screenshot-4.jpg      | Bin 0 -> 64993 bytes
 plugins/google-authenticator/screenshot-5.jpg      | Bin 0 -> 24141 bytes
 22 files changed, 1706 insertions(+)

diff --git a/plugins/google-authenticator/base32.php 
b/plugins/google-authenticator/base32.php
new file mode 100644
index 0000000..91bd93e
--- /dev/null
+++ b/plugins/google-authenticator/base32.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * Encode in Base32 based on RFC 4648.
+ * Requires 20% more space than base64 
+ * Great for case-insensitive filesystems like Windows and URL's  (except for 
= char which can be excluded using the pad option for urls)
+ *
+ * @package default
+ * @author Bryan Ruiz
+ **/
+class Base32 {
+
+   private static $map = array(
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
+        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
+        'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
+        '='  // padding char
+    );
+   
+   private static $flippedMap = array(
+        'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 
'H'=>'7',
+        'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 
'O'=>'14', 'P'=>'15',
+        'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 
'W'=>'22', 'X'=>'23',
+        'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', 
'6'=>'30', '7'=>'31'
+    );
+   
+    /**
+     *    Use padding false when encoding for urls
+     *
+     * @return base32 encoded string
+     * @author Bryan Ruiz
+     **/
+    public static function encode($input, $padding = true) {
+        if(empty($input)) return "";
+        $input = str_split($input);
+        $binaryString = "";
+        for($i = 0; $i < count($input); $i++) {
+            $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, 
'0', STR_PAD_LEFT);
+        }
+        $fiveBitBinaryArray = str_split($binaryString, 5);
+        $base32 = "";
+        $i=0;
+        while($i < count($fiveBitBinaryArray)) {   
+            $base32 .= 
self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
+            $i++;
+        }
+        if($padding && ($x = strlen($binaryString) % 40) != 0) {
+            if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
+            else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
+            else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
+            else if($x == 32) $base32 .= self::$map[32];
+        }
+        return $base32;
+    }
+   
+    public static function decode($input) {
+        if(empty($input)) return;
+        $paddingCharCount = substr_count($input, self::$map[32]);
+        $allowedValues = array(6,4,3,1,0);
+        if(!in_array($paddingCharCount, $allowedValues)) return false;
+        for($i=0; $i<4; $i++){
+            if($paddingCharCount == $allowedValues[$i] &&
+                substr($input, -($allowedValues[$i])) != 
str_repeat(self::$map[32], $allowedValues[$i])) return false;
+        }
+        $input = str_replace('=','', $input);
+        $input = str_split($input);
+        $binaryString = "";
+        for($i=0; $i < count($input); $i = $i+8) {
+            $x = "";
+            if(!in_array($input[$i], self::$map)) return false;
+            for($j=0; $j < 8; $j++) {
+                $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + 
$j]], 10, 2), 5, '0', STR_PAD_LEFT);
+            }
+            $eightBits = str_split($x, 8);
+            for($z = 0; $z < count($eightBits); $z++) {
+                $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 
10))) || ord($y) == 48 ) ? $y:"";
+            }
+        }
+        return $binaryString;
+    }
+}
\ No newline at end of file

diff --git a/plugins/google-authenticator/google-authenticator.php 
b/plugins/google-authenticator/google-authenticator.php
new file mode 100644
index 0000000..a2c46d8
--- /dev/null
+++ b/plugins/google-authenticator/google-authenticator.php
@@ -0,0 +1,549 @@
+<?php
+/*
+Plugin Name: Google Authenticator
+Plugin URI: http://henrik.schack.dk/google-authenticator-for-wordpress
+Description: Two-Factor Authentication for WordPress using the 
Android/iPhone/Blackberry app as One Time Password generator.
+Author: Henrik Schack
+Version: 0.48
+Author URI: http://henrik.schack.dk/
+Compatibility: WordPress 4.5
+Text Domain: google-authenticator
+Domain Path: /lang
+
+----------------------------------------------------------------------------
+
+       Thanks to Bryan Ruiz for his Base32 encode/decode class, found at 
php.net.
+       Thanks to Tobias B�thge for his major code rewrite and German 
translation.
+       Thanks to Pascal de Bruijn for his relaxed mode idea.
+       Thanks to Daniel Werl for his usability tips.
+       Thanks to Dion Hulse for his bugfixes.
+       Thanks to Aldo Latino for his Italian translation.
+       Thanks to Kaijia Feng for his Simplified Chinese translation.
+       Thanks to Ian Dunn for fixing some depricated function calls.
+       Thanks to Kimmo Suominen for fixing the iPhone description issue.
+       Thanks to Alex Concha for some security tips.
+       Thanks to S�bastien Prunier for his Spanish and French translations.
+
+----------------------------------------------------------------------------
+
+    Copyright 2013  Henrik Schack  (email : hen...@schack.dk)
+
+    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 2 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
+*/
+
+class GoogleAuthenticator {
+
+static $instance; // to store a reference to the plugin, allows other plugins 
to remove actions
+
+/**
+ * Constructor, entry point of the plugin
+ */
+function __construct() {
+    self::$instance = $this;
+    add_action( 'init', array( $this, 'init' ) );
+}
+
+/**
+ * Initialization, Hooks, and localization
+ */
+function init() {
+    require_once( 'base32.php' );
+    
+    add_action( 'login_form', array( $this, 'loginform' ) );
+    add_action( 'login_footer', array( $this, 'loginfooter' ) );
+    add_filter( 'authenticate', array( $this, 'check_otp' ), 50, 3 );
+
+    if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
+        add_action( 'wp_ajax_GoogleAuthenticator_action', array( $this, 
'ajax_callback' ) );
+    }
+
+    add_action( 'personal_options_update', array( $this, 
'personal_options_update' ) );
+    add_action( 'profile_personal_options', array( $this, 
'profile_personal_options' ) );
+    add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
+    add_action( 'edit_user_profile_update', array( $this, 
'edit_user_profile_update' ) );
+
+       add_action('admin_enqueue_scripts', array($this, 'add_qrcode_script'));
+
+    load_plugin_textdomain( 'google-authenticator', false, basename( dirname( 
__FILE__ ) ) . '/lang' );
+}
+
+
+/**
+ * Check the verification code entered by the user.
+ */
+function verify( $secretkey, $thistry, $relaxedmode, $lasttimeslot ) {
+
+       // Did the user enter 6 digits ?
+       if ( strlen( $thistry ) != 6) {
+               return false;
+       } else {
+               $thistry = intval ( $thistry );
+       }
+
+       // If user is running in relaxed mode, we allow more time drifting
+       // �4 min, as opposed to � 30 seconds in normal mode.
+       if ( $relaxedmode == 'enabled' ) {
+               $firstcount = -8;
+               $lastcount  =  8; 
+       } else {
+               $firstcount = -1;
+               $lastcount  =  1;       
+       }
+       
+       $tm = floor( time() / 30 );
+       
+       $secretkey=Base32::decode($secretkey);
+       // Keys from 30 seconds before and after are valid aswell.
+       for ($i=$firstcount; $i<=$lastcount; $i++) {
+               // Pack time into binary string
+               $time=chr(0).chr(0).chr(0).chr(0).pack('N*',$tm+$i);
+               // Hash it with users secret key
+               $hm = hash_hmac( 'SHA1', $time, $secretkey, true );
+               // Use last nipple of result as index/offset
+               $offset = ord(substr($hm,-1)) & 0x0F;
+               // grab 4 bytes of the result
+               $hashpart=substr($hm,$offset,4);
+               // Unpak binary value
+               $value=unpack("N",$hashpart);
+               $value=$value[1];
+               // Only 32 bits
+               $value = $value & 0x7FFFFFFF;
+               $value = $value % 1000000;
+               if ( $value === $thistry ) {
+                       // Check for replay (Man-in-the-middle) attack.
+                       // Since this is not Star Trek, time can only move 
forward,
+                       // meaning current login attempt has to be in the 
future compared to
+                       // last successful login.
+                       if ( $lasttimeslot >= ($tm+$i) ) {
+                               error_log("Google Authenticator plugin: 
Man-in-the-middle attack detected (Could also be 2 legit login attempts within 
the same 30 second period)");
+                               return false;
+                       }
+                       // Return timeslot in which login happened.
+                       return $tm+$i;
+               }
+       }
+       return false;
+}
+
+/**
+ * Create a new random secret for the Google Authenticator app.
+ * 16 characters, randomly chosen from the allowed Base32 characters
+ * equals 10 bytes = 80 bits, as 256^10 = 32^16 = 2^80
+ */ 
+function create_secret() {
+    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; // allowed characters in 
Base32
+    $secret = '';
+    for ( $i = 0; $i < 16; $i++ ) {
+        $secret .= substr( $chars, wp_rand( 0, strlen( $chars ) - 1 ), 1 );
+    }
+    return $secret;
+}
+
+/**
+ * Add the script to generate QR codes.
+ */
+function add_qrcode_script() {
+    wp_enqueue_script('jquery');
+    wp_register_script('qrcode_script', plugins_url('jquery.qrcode.min.js', 
__FILE__),array("jquery"));
+    wp_enqueue_script('qrcode_script');
+}
+
+/**
+ * Add verification code field to login form.
+ */
+function loginform() {
+    echo "\t<p>\n";
+    echo "\t\t<label title=\"".__('If you don\'t have Google Authenticator 
enabled for your WordPress account, leave this field 
empty.','google-authenticator')."\">".__('Google Authenticator 
code','google-authenticator')."<span id=\"google-auth-info\"></span><br />\n";
+    echo "\t\t<input type=\"text\" name=\"googleotp\" id=\"user_email\" 
class=\"input\" value=\"\" size=\"20\" style=\"ime-mode: inactive;\" 
/></label>\n";
+    echo "\t</p>\n";
+}
+
+/**
+ * Disable autocomplete on Google Authenticator code input field.
+ */
+function loginfooter() {
+    echo "\n<script type=\"text/javascript\">\n";
+    echo "\ttry{\n";
+    echo 
"\t\tdocument.getElementById('user_email').setAttribute('autocomplete','off');\n";
+    echo "\t} catch(e){}\n";
+    echo "</script>\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.
+       if ( get_user_by( 'email', $username ) === false ) {
+               $user = get_user_by( 'login', $username );
+       } else {
+               $user = get_user_by( 'email', $username );
+       }
+
+       // Does the user have the Google Authenticator enabled ?
+       if ( isset( $user->ID ) && 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
+               if ( !empty( $_POST['googleotp'] )) { // Prevent PHP notices 
when using app password login
+                       $otp = trim( $_POST[ 'googleotp' ] );
+               } else {
+                       $otp = '';
+               }
+               // When was the last successful login performed ?
+               $lasttimeslot = trim( get_user_option( 
'googleauthenticator_lasttimeslot', $user->ID ) );
+               // Valid code ?
+               if ( $timeslot = $this->verify( $GA_secret, $otp, 
$GA_relaxedmode, $lasttimeslot ) ) {
+                       // Store the timeslot in which login was successful.
+                       update_user_option( $user->ID, 
'googleauthenticator_lasttimeslot', $timeslot, true );
+                       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 ) );
+                               $passwordhash   = 
trim($GA_passwords->{'password'} );
+                               $usersha1               = sha1( strtoupper( 
str_replace( ' ', '', $password ) ) );
+                               if ( $passwordhash == $usersha1 ) { // ToDo: 
Remove after some time when users have migrated to new format
+                                       return new WP_User( $user->ID );
+                                 // Try the new version based on thee 
wp_hash_password function
+                               } elseif (wp_check_password( strtoupper( 
str_replace( ' ', '', $password ) ), $passwordhash)) {
+                                       return new WP_User( $user->ID );
+                               } else {
+                                       // Wrong XMLRPC/APP password !
+                                       return new WP_Error( 
'invalid_google_authenticator_password', __( '<strong>ERROR</strong>: The 
Google Authenticator password is incorrect.', 'google-authenticator' ) );
+                               }                
+                       } else {
+                               return new WP_Error( 
'invalid_google_authenticator_token', __( '<strong>ERROR</strong>: 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 "<h3>".__( 'Google Authenticator Settings', 'google-authenticator' 
)."</h3>\n";
+
+       echo "<table class=\"form-table\">\n";
+       echo "<tbody>\n";
+       echo "<tr>\n";
+       echo "<th scope=\"row\">".__( 'Active', 'google-authenticator' 
)."</th>\n";
+       echo "<td>\n";
+       echo "<input name=\"GA_enabled\" id=\"GA_enabled\" class=\"tog\" 
type=\"checkbox\"" . checked( $GA_enabled, 'enabled', false ) . "/>\n";
+       echo "</td>\n";
+       echo "</tr>\n";
+
+       if ( $is_profile_page || IS_PROFILE_PAGE ) {
+               echo "<tr>\n";
+               echo "<th scope=\"row\">".__( 'Relaxed mode', 
'google-authenticator' )."</th>\n";
+               echo "<td>\n";
+               echo "<input name=\"GA_relaxedmode\" id=\"GA_relaxedmode\" 
class=\"tog\" type=\"checkbox\"" . checked( $GA_relaxedmode, 'enabled', false ) 
. "/><span class=\"description\">".__(' Relaxed mode allows for more time 
drifting on your phone clock (&#177;4 
min).','google-authenticator')."</span>\n";
+               echo "</td>\n";
+               echo "</tr>\n";
+               
+               echo "<tr>\n";
+               echo "<th><label 
for=\"GA_description\">".__('Description','google-authenticator')."</label></th>\n";
+               echo "<td><input name=\"GA_description\" id=\"GA_description\" 
value=\"{$GA_description}\"  type=\"text\" size=\"25\" /><span 
class=\"description\">".__(' Description that you\'ll see in the Google 
Authenticator app on your phone.','google-authenticator')."</span><br 
/></td>\n";
+               echo "</tr>\n";
+
+               echo "<tr>\n";
+               echo "<th><label 
for=\"GA_secret\">".__('Secret','google-authenticator')."</label></th>\n";
+               echo "<td>\n";
+               echo "<input name=\"GA_secret\" id=\"GA_secret\" 
value=\"{$GA_secret}\" readonly=\"readonly\"  type=\"text\" size=\"25\" />";
+               echo "<input name=\"GA_newsecret\" id=\"GA_newsecret\" 
value=\"".__("Create new secret",'google-authenticator')."\"   type=\"button\" 
class=\"button\" />";
+               echo "<input name=\"show_qr\" id=\"show_qr\" 
value=\"".__("Show/Hide QR code",'google-authenticator')."\"   type=\"button\" 
class=\"button\" onclick=\"ShowOrHideQRCode();\" />";
+               echo "</td>\n";
+               echo "</tr>\n";
+
+               echo "<tr>\n";
+               echo "<th></th>\n";
+               echo "<td><div id=\"GA_QR_INFO\" style=\"display: none\" >";
+               echo "<div id=\"GA_QRCODE\"/></div>";
+
+               echo '<span class="description"><br/> ' . __( 'Scan this with 
the Google Authenticator app.', 'google-authenticator' ) . '</span>';
+               echo "</div></td>\n";
+               echo "</tr>\n";
+
+               echo "<tr>\n";
+               echo "<th scope=\"row\">".__( 'Enable App password', 
'google-authenticator' )."</th>\n";
+               echo "<td>\n";
+               echo "<input name=\"GA_pwdenabled\" id=\"GA_pwdenabled\" 
class=\"tog\" type=\"checkbox\"" . checked( $GA_pwdenabled, 'enabled', false ) 
. "/><span class=\"description\">".__(' Enabling an App password will decrease 
your overall login security.','google-authenticator')."</span>\n";
+               echo "</td>\n";
+               echo "</tr>\n";
+               
+               echo "<tr>\n";
+               echo "<th></th>\n";
+               echo "<td>\n";
+               echo "<input name=\"GA_password\" id=\"GA_password\" 
readonly=\"readonly\" value=\"".$GA_password."\" type=\"text\" size=\"25\" />";
+               echo "<input name=\"GA_createpassword\" 
id=\"GA_createpassword\" value=\"".__("Create new 
password",'google-authenticator')."\"   type=\"button\" class=\"button\" />";
+               echo "<span class=\"description\" id=\"GA_passworddesc\"> 
".__(' Password is not stored in cleartext, this is your only chance to see 
it.','google-authenticator')."</span>\n";
+               echo "</td>\n";
+               echo "</tr>\n";
+       }
+
+       echo "</tbody></table>\n";
+       echo "<script type=\"text/javascript\">\n";
+       echo "var 
GAnonce='".wp_create_nonce('GoogleAuthenticatoraction')."';\n";
+
+       echo <<<ENDOFJS
+       //Create new secret and display it
+       jQuery('#GA_newsecret').bind('click', function() {
+               // Remove existing QRCode
+               jQuery('#GA_QRCODE').html("");
+               var data=new Object();
+               data['action']  = 'GoogleAuthenticator_action';
+               data['nonce']   = GAnonce;
+               jQuery.post(ajaxurl, data, function(response) {
+                       jQuery('#GA_secret').val(response['new-secret']);
+                       var 
qrcode="otpauth://totp/WordPress:"+escape(jQuery('#GA_description').val())+"?secret="+jQuery('#GA_secret').val()+"&issuer=WordPress";
+                       jQuery('#GA_QRCODE').qrcode(qrcode);
+                       jQuery('#GA_QR_INFO').show('slow');
+               });     
+       });
+
+       // If the user starts modifying the description, hide the qrcode
+       jQuery('#GA_description').bind('focus blur change keyup', function() {
+               // Only remove QR Code if it's visible
+               if (jQuery('#GA_QR_INFO').is(':visible')) {
+                       jQuery('#GA_QR_INFO').hide('slow');
+                       jQuery('#GA_QRCODE').html("");
+               }
+       });
+
+       // Create new app password
+       jQuery('#GA_createpassword').bind('click',function() {
+               var data=new Object();
+               data['action']  = 'GoogleAuthenticator_action';
+               data['nonce']   = GAnonce;
+               data['save']    = 1;
+               jQuery.post(ajaxurl, data, function(response) {
+                       
jQuery('#GA_password').val(response['new-secret'].match(new 
RegExp(".{0,4}","g")).join(' '));
+                       jQuery('#GA_passworddesc').show();
+               });     
+       });
+       
+       jQuery('#GA_enabled').bind('change',function() {
+               GoogleAuthenticator_apppasswordcontrol();
+       });
+
+       jQuery(document).ready(function() {
+               jQuery('#GA_passworddesc').hide();
+               GoogleAuthenticator_apppasswordcontrol();
+       });
+       
+       function GoogleAuthenticator_apppasswordcontrol() {
+               if (jQuery('#GA_enabled').is(':checked')) {
+                       jQuery('#GA_pwdenabled').removeAttr('disabled');
+                       jQuery('#GA_createpassword').removeAttr('disabled');
+               } else {
+                       jQuery('#GA_pwdenabled').removeAttr('checked')
+                       jQuery('#GA_pwdenabled').attr('disabled', true);
+                       jQuery('#GA_createpassword').attr('disabled', true);
+               }
+       }
+
+       function ShowOrHideQRCode() {
+               if (jQuery('#GA_QR_INFO').is(':hidden')) {
+                       var 
qrcode="otpauth://totp/WordPress:"+escape(jQuery('#GA_description').val())+"?secret="+jQuery('#GA_secret').val()+"&issuer=WordPress";
+                       jQuery('#GA_QRCODE').qrcode(qrcode);
+               jQuery('#GA_QR_INFO').show('slow');
+               } else {
+                       jQuery('#GA_QR_INFO').hide('slow');
+                       jQuery('#GA_QRCODE').html("");
+               }
+       }
+</script>
+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( sanitize_text_field($_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' => 
wp_hash_password( $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', 
$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 );
+
+}
+
+/**
+ * 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 "<h3>".__('Google Authenticator 
Settings','google-authenticator')."</h3>\n";
+       echo "<table class=\"form-table\">\n";
+       echo "<tbody>\n";
+
+       echo "<tr>\n";
+       echo "<th scope=\"row\">".__('Hide settings from 
user','google-authenticator')."</th>\n";
+       echo "<td>\n";
+       echo "<div><input name=\"GA_hidefromuser\" id=\"GA_hidefromuser\"  
class=\"tog\" type=\"checkbox\"" . checked( $GA_hidefromuser, 'enabled', false 
) . "/>\n";
+       echo "</td>\n";
+       echo "</tr>\n";
+
+       echo "<tr>\n";
+       echo "<th scope=\"row\">".__('Active','google-authenticator')."</th>\n";
+       echo "<td>\n";
+       echo "<div><input name=\"GA_enabled\" id=\"GA_enabled\"  class=\"tog\" 
type=\"checkbox\"" . checked( $GA_enabled, 'enabled', false ) . "/>\n";
+       echo "</td>\n";
+       echo "</tr>\n";
+
+       echo "</tbody>\n";
+       echo "</table>\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.
+       $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;
+?>

diff --git a/plugins/google-authenticator/jquery.qrcode.min.js 
b/plugins/google-authenticator/jquery.qrcode.min.js
new file mode 100644
index 0000000..fe9680e
--- /dev/null
+++ b/plugins/google-authenticator/jquery.qrcode.min.js
@@ -0,0 +1,28 @@
+(function(r){r.fn.qrcode=function(h){var s;function 
u(a){this.mode=s;this.data=a}function 
o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function
 q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var 
d=0;d<a.length&&0==a[d];)d++;this.num=Array(a.length-d+c);for(var 
b=0;b<a.length-d;b++)this.num[b]=a[b+d]}function 
p(a,c){this.totalCount=a;this.dataCount=c}function 
t(){this.buffer=[];this.length=0}u.prototype={getLength:function(){return 
this.data.length},
+write:function(a){for(var 
c=0;c<this.data.length;c++)a.put(this.data.charCodeAt(c),8)}};o.prototype={addData:function(a){this.dataList.push(new
 
u(a));this.dataCache=null},isDark:function(a,c){if(0>a||this.moduleCount<=a||0>c||this.moduleCount<=c)throw
 Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return 
this.moduleCount},make:function(){if(1>this.typeNumber){for(var 
a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new 
t,b=0,e=0;e<c.length;e++)b+=c[e].dataCount;
+for(e=0;e<this.dataList.length;e++)c=this.dataList[e],d.put(c.mode,4),d.put(c.getLength(),j.getLengthInBits(c.mode,a)),c.write(d);if(d.getLengthInBits()<=8*b)break}this.typeNumber=a}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17;this.modules=Array(this.moduleCount);for(var
 d=0;d<this.moduleCount;d++){this.modules[d]=Array(this.moduleCount);for(var 
b=0;b<this.moduleCount;b++)this.modules[d][b]=null}this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-
+7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(a,c);7<=this.typeNumber&&this.setupTypeNumber(a);null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,c){for(var
 d=-1;7>=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var 
b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
+0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var
 a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var 
b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return 
c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c<this.modules.length;c++)for(var
 d=1*c,b=0;b<this.modules[c].length;b++){var 
e=1*b;this.modules[c][b]&&(a.beginFill(0,100),a.moveTo(e,d),a.lineTo(e+1,d),a.lineTo(e+1,d+1),a.lineTo(e,d+1),a.endFill())}return
 a},
+setupTimingPattern:function(){for(var 
a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(a=8;a<this.moduleCount-8;a++)null==this.modules[6][a]&&(this.modules[6][a]=0==a%2)},setupPositionAdjustPattern:function(){for(var
 a=j.getPatternPosition(this.typeNumber),c=0;c<a.length;c++)for(var 
d=0;d<a.length;d++){var b=a[c],e=a[d];if(null==this.modules[b][e])for(var 
f=-2;2>=f;f++)for(var 
i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var
 c=
+j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var 
b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var
 d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var 
e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
+b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var
 
d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0<i;i-=2)for(6==i&&i--;;){for(var
 g=0;2>g;g++)if(null==this.modules[b][i-g]){var 
n=!1;f<a.length&&(n=1==(a[f]>>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--;
 
-1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var
 c=p.getRSBlocks(a,
+c),b=new t,e=0;e<d.length;e++){var 
f=d[e];b.put(f.mode,4);b.put(f.getLength(),j.getLengthInBits(f.mode,a));f.write(b)}for(e=a=0;e<c.length;e++)a+=c[e].dataCount;if(b.getLengthInBits()>8*a)throw
 Error("code length overflow. 
("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return
 o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
+0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g<c.length;g++){var 
n=c[g].dataCount,h=c[g].totalCount-n,b=Math.max(b,n),e=Math.max(e,h);f[g]=Array(n);for(var
 
k=0;k<f[g].length;k++)f[g][k]=255&a.buffer[k+d];d+=n;k=j.getErrorCorrectPolynomial(h);n=(new
 
q(f[g],k.getLength()-1)).mod(k);i[g]=Array(k.getLength()-1);for(k=0;k<i[g].length;k++)h=k+n.getLength()-i[g].length,i[g][k]=0<=h?n.get(h):0}for(k=g=0;k<c.length;k++)g+=c[k].totalCount;d=Array(g);for(k=n=0;k<b;k++)for(g=0;g<c.length;g++)k<f[g].length&&
+(d[n++]=f[g][k]);for(k=0;k<e;k++)for(g=0;g<c.length;g++)k<i[g].length&&(d[n++]=i[g][k]);return
 d};s=4;for(var 
j={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,
+78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var
 
c=a<<10;0<=j.getBCHDigit(c)-j.getBCHDigit(j.G15);)c^=j.G15<<j.getBCHDigit(c)-j.getBCHDigit(j.G15);return(a<<10|c)^j.G15_MASK},getBCHTypeNumber:function(a){for(var
 c=a<<12;0<=j.getBCHDigit(c)-
+j.getBCHDigit(j.G18);)c^=j.G18<<j.getBCHDigit(c)-j.getBCHDigit(j.G18);return 
a<<12|c},getBCHDigit:function(a){for(var c=0;0!=a;)c++,a>>>=1;return 
c},getPatternPosition:function(a){return 
j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 
0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 
0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 
0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 
0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
+a);}},getErrorCorrectPolynomial:function(a){for(var c=new 
q([1],0),d=0;d<a;d++)c=c.multiply(new q([1,l.gexp(d)],0));return 
c},getLengthInBits:function(a,c){if(1<=c&&10>c)switch(a){case 1:return 10;case 
2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else 
if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 
8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 
1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw 
Error("mode:"+
+a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var 
c=a.getModuleCount(),d=0,b=0;b<c;b++)for(var e=0;e<c;e++){for(var 
f=0,i=a.isDark(b,e),g=-1;1>=g;g++)if(!(0>b+g||c<=b+g))for(var 
h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5<f&&(d+=3+f-5)}for(b=0;b<c-1;b++)for(e=0;e<c-1;e++)if(f=0,a.isDark(b,e)&&f++,a.isDark(b+1,e)&&f++,a.isDark(b,e+1)&&f++,a.isDark(b+1,e+1)&&f++,0==f||4==f)d+=3;for(b=0;b<c;b++)for(e=0;e<c-6;e++)a.isDark(b,e)&&!a.isDark(b,e+1)&&a.isDark(b,e+
+2)&&a.isDark(b,e+3)&&a.isDark(b,e+4)&&!a.isDark(b,e+5)&&a.isDark(b,e+6)&&(d+=40);for(e=0;e<c;e++)for(b=0;b<c-6;b++)a.isDark(b,e)&&!a.isDark(b+1,e)&&a.isDark(b+2,e)&&a.isDark(b+3,e)&&a.isDark(b+4,e)&&!a.isDark(b+5,e)&&a.isDark(b+6,e)&&(d+=40);for(e=f=0;e<c;e++)for(b=0;b<c;b++)a.isDark(b,e)&&f++;a=Math.abs(100*f/c/c-50)/5;return
 d+10*a}},l={glog:function(a){if(1>a)throw Error("glog("+a+")");return 
l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return 
l.EXP_TABLE[a]},EXP_TABLE:Array(256),
+LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<<m;for(m=8;256>m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return
 this.num[a]},getLength:function(){return 
this.num.length},multiply:function(a){for(var 
c=Array(this.getLength()+a.getLength()-1),d=0;d<this.getLength();d++)for(var 
b=0;b<a.getLength();b++)c[d+b]^=l.gexp(l.glog(this.get(d))+l.glog(a.get(b)));return
 new q(c,0)},mod:function(a){if(0>
+this.getLength()-a.getLength())return this;for(var 
c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b<this.getLength();b++)d[b]=this.get(b);for(b=0;b<a.getLength();b++)d[b]^=l.gexp(l.glog(a.get(b))+c);return(new
 
q(d,0)).mod(a)}};p.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],
+[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,
+116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,
+43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,
+3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,
+55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
+45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var
 d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ 
typeNumber:"+a+"/errorCorrectLevel:"+c);for(var 
b=d.length/3,e=[],f=0;f<b;f++)for(var 
h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return 
e};p.getRsBlockTable=function(a,c){switch(c){case 1:return 
p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 
3:return p.RS_BLOCK_TABLE[4*
+(a-1)+2];case 2:return 
p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 
1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var 
d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return 
this.length},putBit:function(a){var 
c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof
 
h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
+correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return 
this.each(function(){var a;if("canvas"==h.render){a=new 
o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var 
c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var 
d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var
 
i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var
 g=Math.ceil((i+1)*b)-Math.floor(i*b),
+j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new
 
o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
+d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);

diff --git a/plugins/google-authenticator/lang/google-authenticator-da_DK.mo 
b/plugins/google-authenticator/lang/google-authenticator-da_DK.mo
new file mode 100644
index 0000000..d4b4b1f
Binary files /dev/null and 
b/plugins/google-authenticator/lang/google-authenticator-da_DK.mo differ

diff --git a/plugins/google-authenticator/lang/google-authenticator-da_DK.po 
b/plugins/google-authenticator/lang/google-authenticator-da_DK.po
new file mode 100644
index 0000000..28fe991
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator-da_DK.po
@@ -0,0 +1,113 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator\n"
+"POT-Creation-Date: 2014-01-11 08:17+0100\n"
+"PO-Revision-Date: 2014-01-11 08:20+0100\n"
+"Last-Translator: Henrik Schack <hen...@schack.dk>\n"
+"Language-Team: \n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.6.3\n"
+"X-Poedit-Basepath: ..\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
+"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
+"_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-SearchPath-0: .\n"
+
+#: google-authenticator.php:166
+msgid ""
+"If you don't have Google Authenticator enabled for your WordPress account, "
+"leave this field empty."
+msgstr ""
+"Hvis ikke du har aktiveret Google Authenticator for din konto, så lad være "
+"med at skrive noget her."
+
+#: google-authenticator.php:166
+msgid "Google Authenticator code"
+msgstr "Google Authenticator kode"
+
+#: google-authenticator.php:231
+msgid "<strong>ERROR</strong>: The Google Authenticator password is incorrect."
+msgstr "<strong>ERROR</strong>: Google Authenticator kodeordet er forkert."
+
+#: google-authenticator.php:234
+msgid ""
+"<strong>ERROR</strong>: The Google Authenticator code is incorrect or has "
+"expired."
+msgstr ""
+"<strong>ERROR</strong>: Google Authenticator koden er forkert eller udløbet."
+
+#: google-authenticator.php:274
+msgid "WordPressBlog"
+msgstr "WordPressBlog"
+
+#: google-authenticator.php:277 google-authenticator.php:469
+msgid "Google Authenticator Settings"
+msgstr "Google Authenticator indstillinger"
+
+#: google-authenticator.php:282 google-authenticator.php:481
+msgid "Active"
+msgstr "Aktiv"
+
+#: google-authenticator.php:290
+msgid "Relaxed mode"
+msgstr "Afslappet tilstand"
+
+#: google-authenticator.php:292
+msgid ""
+" Relaxed mode allows for more time drifting on your phone clock (&#177;4 "
+"min)."
+msgstr ""
+"Afslappet tilstand tillader mere upræcis tid på din telefon (&#177;4 min)."
+
+#: google-authenticator.php:297
+msgid "Description"
+msgstr "Beskrivelse"
+
+#: google-authenticator.php:298
+msgid ""
+" Description that you'll see in the Google Authenticator app on your phone."
+msgstr "Beskrivelsen du vil se i Google Authenticator app'en på din telefon."
+
+#: google-authenticator.php:302
+msgid "Secret"
+msgstr "Hemmelig kode"
+
+#: google-authenticator.php:305
+msgid "Create new secret"
+msgstr "Opret ny hemmelig kode"
+
+#: google-authenticator.php:306
+msgid "Show/Hide QR code"
+msgstr "Vis/Gem QR kode"
+
+#: google-authenticator.php:315
+msgid "Scan this with the Google Authenticator app."
+msgstr "Scan dette med Google Authenticator app'en."
+
+#: google-authenticator.php:320
+msgid "Enable App password"
+msgstr "Aktiver app kodeord"
+
+#: google-authenticator.php:322
+msgid " Enabling an App password will decrease your overall login security."
+msgstr ""
+"Aktiverer du app kodeords featuren, påvirker det din sikkerhed generelt."
+
+#: google-authenticator.php:330
+msgid "Create new password"
+msgstr "Opret nyt kodeord"
+
+#: google-authenticator.php:331
+msgid ""
+" Password is not stored in cleartext, this is your only chance to see it."
+msgstr ""
+"Kodeordet gemmes ikke i klartekst, dette er din eneste chance for at se det."
+
+#: google-authenticator.php:474
+msgid "Hide settings from user"
+msgstr "Skjul indstillinger for bruger"

diff --git a/plugins/google-authenticator/lang/google-authenticator-de_DE.mo 
b/plugins/google-authenticator/lang/google-authenticator-de_DE.mo
new file mode 100644
index 0000000..3ac64c7
Binary files /dev/null and 
b/plugins/google-authenticator/lang/google-authenticator-de_DE.mo differ

diff --git a/plugins/google-authenticator/lang/google-authenticator-de_DE.po 
b/plugins/google-authenticator/lang/google-authenticator-de_DE.po
new file mode 100644
index 0000000..66afca4
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator-de_DE.po
@@ -0,0 +1,119 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator 0.30\n"
+"Report-Msgid-Bugs-To: http://wordpress.org/tag/google-authenticator\n";
+"POT-Creation-Date: 2011-05-17 19:38:36+00:00\n"
+"PO-Revision-Date: 2011-06-25 16:20+0100\n"
+"Last-Translator: Tobias Bäthge <wordpr...@tobias.baethge.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: \n"
+"X-Poedit-Country: \n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Poedit-KeywordsList: 
__;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
+"X-Poedit-Basepath: \n"
+"X-Poedit-Bookmarks: \n"
+"X-Poedit-SearchPath-0: .\n"
+"X-Textdomain-Support: yes"
+
+#: google-authenticator.php:118
+#@ google-authenticator
+msgid "Google Authenticator code"
+msgstr "&quot;Google Authenticator&quot;-Code"
+
+#: google-authenticator.php:172
+#: google-authenticator.php:267
+#@ google-authenticator
+msgid "Active"
+msgstr "Aktivieren"
+
+#: google-authenticator.php:184
+#@ google-authenticator
+msgid "Description"
+msgstr "Beschreibung"
+
+#: google-authenticator.php:189
+#@ google-authenticator
+msgid "Secret"
+msgstr "Geheimschlüssel"
+
+#: google-authenticator.php:192
+#@ google-authenticator
+msgid "Create new secret"
+msgstr "Neuen Geheimschlüssel erzeugen"
+
+#: google-authenticator.php:193
+#@ google-authenticator
+msgid "Show/Hide QR code"
+msgstr "QR-Code anzeigen/verstecken"
+
+#. translators: plugin header field 'Name'
+#: google-authenticator.php:0
+#@ google-authenticator
+msgid "Google Authenticator"
+msgstr "Google Authenticator"
+
+#. translators: plugin header field 'PluginURI'
+#: google-authenticator.php:0
+#@ google-authenticator
+msgid "http://henrik.schack.dk/google-authenticator-for-wordpress";
+msgstr "http://henrik.schack.dk/google-authenticator-for-wordpress";
+
+#. translators: plugin header field 'Author'
+#: google-authenticator.php:0
+#@ google-authenticator
+msgid "Henrik Schack"
+msgstr "Henrik Schack"
+
+#. translators: plugin header field 'AuthorURI'
+#: google-authenticator.php:0
+#@ google-authenticator
+msgid "http://henrik.schack.dk/";
+msgstr "http://henrik.schack.dk/";
+
+#. translators: plugin header field 'Version'
+#: google-authenticator.php:0
+#@ google-authenticator
+msgid "0.30"
+msgstr "0.30"
+
+#: google-authenticator.php:143
+#@ google-authenticator
+msgid "<strong>ERROR</strong>: The Google Authenticator code is incorrect or 
has expired."
+msgstr "<strong>FEHLER</strong>: Der eingegebene &quot;Google 
Authenticator&quot;-Code ist falsch oder abgelaufen."
+
+#: google-authenticator.php:165
+#@ google-authenticator
+msgid "WordPress Blog"
+msgstr "WordPress-Blog"
+
+#: google-authenticator.php:167
+#: google-authenticator.php:263
+#@ google-authenticator
+msgid "Google Authenticator Settings"
+msgstr "Einstellungen zu Google Authenticator"
+
+#: google-authenticator.php:201
+#@ google-authenticator
+msgid "Scan this with the Google Authenticator app."
+msgstr "Scanne diesen QR-Code mit der &quot;Google Authenticator&quot;-App 
deines Smartphones."
+
+#: google-authenticator.php:118
+#@ google-authenticator
+msgid "If you don't have Google Authenticator enabled for your WordPress 
account, leave this field empty."
+msgstr "Falls die Nutzung von &quot;Google Authenticator&quot; für dieses 
WordPress-Konto nicht aktiviert ist, dieses Feld leer lassen."
+
+#: google-authenticator.php:185
+#@ google-authenticator
+msgid " Description that you'll see in the Google Authenticator app on your 
phone."
+msgstr "Beschreibung, die in der &quot;Google Authenticator&quot;-App auf dem 
Smartphone angezeigt wird."
+
+#. translators: plugin header field 'Description'
+#: google-authenticator.php:0
+#@ google-authenticator
+msgid "Two-Factor Authentication for WordPress using the 
Android/iPhone/Blackberry app as One Time Password generator."
+msgstr "Zwei-Faktor-Authentifizierung für WordPress mit der &quot;Google 
Authenticator&quot;-App für Android/iPhone/Blackberry"
+

diff --git a/plugins/google-authenticator/lang/google-authenticator-es_ES.mo 
b/plugins/google-authenticator/lang/google-authenticator-es_ES.mo
new file mode 100644
index 0000000..5bf1304
Binary files /dev/null and 
b/plugins/google-authenticator/lang/google-authenticator-es_ES.mo differ

diff --git a/plugins/google-authenticator/lang/google-authenticator-es_ES.po 
b/plugins/google-authenticator/lang/google-authenticator-es_ES.po
new file mode 100644
index 0000000..ce9ab6a
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator-es_ES.po
@@ -0,0 +1,131 @@
+# Copyright (C) 2010 Google Authenticator
+# This file is distributed under the same license as the Google Authenticator 
package.
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator 0.37\n"
+"Report-Msgid-Bugs-To: http://wordpress.org/tag/google-authenticator\n";
+"POT-Creation-Date: 2011-08-21 14:25:45+00:00\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"PO-Revision-Date: 2014-01-11 10:07+0100\n"
+"Last-Translator: \n"
+"Language-Team: LANGUAGE <l...@li.org>\n"
+"X-Generator: Poedit 1.6.3\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Language: es_ES\n"
+
+#: google-authenticator.php:131
+msgid ""
+"If you don't have Google Authenticator enabled for your WordPress account, "
+"leave this field empty."
+msgstr ""
+"Si no tiene Google Authenticator habilitado en su cuenta de WordPress, deje "
+"este campo vacío."
+
+#: google-authenticator.php:131
+msgid "Google Authenticator code"
+msgstr "Código Google Authenticator"
+
+#: google-authenticator.php:176
+msgid "<strong>ERROR</strong>: The Google Authenticator password is incorrect."
+msgstr "<strong>ERROR</strong>: El codigo es incorrecto."
+
+#: google-authenticator.php:179
+msgid ""
+"<strong>ERROR</strong>: The Google Authenticator code is incorrect or has "
+"expired."
+msgstr "<strong>ERROR</strong>: El código es incorrecto o caducado."
+
+#: google-authenticator.php:215
+msgid "WordPress Blog"
+msgstr "Blog de WordPress"
+
+#: google-authenticator.php:218 google-authenticator.php:392
+msgid "Google Authenticator Settings"
+msgstr "Opciones Google Authenticator"
+
+#: google-authenticator.php:223 google-authenticator.php:396
+msgid "Active"
+msgstr "Activar"
+
+#: google-authenticator.php:235
+msgid "Relaxed mode"
+msgstr "Modo relajado"
+
+#: google-authenticator.php:237
+msgid ""
+" Relaxed mode allows for more time drifting on your phone clock (&#177;4 "
+"min)."
+msgstr ""
+"El modo relajado permite tener más tiempo de reloj en su teléfono (&#177;4 "
+"min)."
+
+#: google-authenticator.php:242
+msgid "Description"
+msgstr "Descripción"
+
+#: google-authenticator.php:243
+msgid ""
+" Description that you'll see in the Google Authenticator app on your phone."
+msgstr ""
+"Descripción que se verá en la aplicación Google Authenticator en su teléfono."
+
+#: google-authenticator.php:247
+msgid "Secret"
+msgstr "Secreto"
+
+#: google-authenticator.php:250
+msgid "Create new secret"
+msgstr "Crear nueva clave secreta"
+
+#: google-authenticator.php:251
+msgid "Show/Hide QR code"
+msgstr "Mostar/Esconder QR Code"
+
+#: google-authenticator.php:259
+msgid "Scan this with the Google Authenticator app."
+msgstr "Escanear esto con la aplicación Google Authenticator."
+
+#: google-authenticator.php:264
+msgid "Enable App password"
+msgstr "Permitir contraseña de aplicación"
+
+#: google-authenticator.php:266
+msgid " Enabling an App password will decrease your overall login security."
+msgstr "Permitir una contraseña de aplicación disminuirá su seguridad global."
+
+#: google-authenticator.php:274
+msgid "Create new password"
+msgstr "Crear nueva contraseña"
+
+#: google-authenticator.php:275
+msgid ""
+" Password is not stored in cleartext, this is your only chance to see it."
+msgstr ""
+"La contraseña no está almacenada en formato de texto, es su única "
+"oportunidad de verla."
+
+#. Plugin Name of the plugin/theme
+msgid "Google Authenticator"
+msgstr ""
+
+#. Plugin URI of the plugin/theme
+msgid "http://henrik.schack.dk/google-authenticator-for-wordpress";
+msgstr ""
+
+#. Description of the plugin/theme
+msgid ""
+"Two-Factor Authentication for WordPress using the Android/iPhone/Blackberry "
+"app as One Time Password generator."
+msgstr ""
+"La autentificación en dos pasos por wordpress utiliza una app Android/iPhone/"
+"Blackberry como 'One Time Password generator.'"
+
+#. Author of the plugin/theme
+msgid "Henrik Schack"
+msgstr ""
+
+#. Author URI of the plugin/theme
+msgid "http://henrik.schack.dk/";
+msgstr ""

diff --git a/plugins/google-authenticator/lang/google-authenticator-fr_FR.mo 
b/plugins/google-authenticator/lang/google-authenticator-fr_FR.mo
new file mode 100644
index 0000000..000ac74
Binary files /dev/null and 
b/plugins/google-authenticator/lang/google-authenticator-fr_FR.mo differ

diff --git a/plugins/google-authenticator/lang/google-authenticator-fr_FR.po 
b/plugins/google-authenticator/lang/google-authenticator-fr_FR.po
new file mode 100644
index 0000000..9dcbd95
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator-fr_FR.po
@@ -0,0 +1,133 @@
+# Copyright (C) 2010 Google Authenticator
+# This file is distributed under the same license as the Google Authenticator 
package.
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator 0.37\n"
+"Report-Msgid-Bugs-To: http://wordpress.org/tag/google-authenticator\n";
+"POT-Creation-Date: 2011-08-21 14:25:45+00:00\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"PO-Revision-Date: 2014-01-11 10:15+0100\n"
+"Last-Translator: \n"
+"Language-Team: LANGUAGE <l...@li.org>\n"
+"X-Generator: Poedit 1.6.3\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Language: fr_FR\n"
+
+#: google-authenticator.php:131
+msgid ""
+"If you don't have Google Authenticator enabled for your WordPress account, "
+"leave this field empty."
+msgstr ""
+"Si vous n'avez pas activé Google ASuthenticator pour votre compte wordpress, "
+"laissez ce champ vide."
+
+#: google-authenticator.php:131
+msgid "Google Authenticator code"
+msgstr "Code Google Authenticator"
+
+#: google-authenticator.php:176
+msgid "<strong>ERROR</strong>: The Google Authenticator password is incorrect."
+msgstr "<strong>ERREUR</strong>: Le code Google Authenticator est incorrect."
+
+#: google-authenticator.php:179
+msgid ""
+"<strong>ERROR</strong>: The Google Authenticator code is incorrect or has "
+"expired."
+msgstr ""
+"<strong>ERREUR</strong>: Le code Google Authenticator est incorrect ou "
+"périmé."
+
+#: google-authenticator.php:215
+msgid "WordPress Blog"
+msgstr "Blog WordPress"
+
+#: google-authenticator.php:218 google-authenticator.php:392
+msgid "Google Authenticator Settings"
+msgstr "Réglages Google Authenticator"
+
+#: google-authenticator.php:223 google-authenticator.php:396
+msgid "Active"
+msgstr "Activer"
+
+#: google-authenticator.php:235
+msgid "Relaxed mode"
+msgstr "Mode relax"
+
+#: google-authenticator.php:237
+msgid ""
+" Relaxed mode allows for more time drifting on your phone clock (&#177;4 "
+"min)."
+msgstr ""
+"Le mode relax vous permet d'avoir plus de temps de latence sur le chrono de "
+"votre téléphone (&#177;4 min)."
+
+#: google-authenticator.php:242
+msgid "Description"
+msgstr "Description"
+
+#: google-authenticator.php:243
+msgid ""
+" Description that you'll see in the Google Authenticator app on your phone."
+msgstr ""
+"Voici la description que vous verrez dans l'app Gogogle Authentiator de "
+"votre téléphone."
+
+#: google-authenticator.php:247
+msgid "Secret"
+msgstr "Code secret"
+
+#: google-authenticator.php:250
+msgid "Create new secret"
+msgstr "Créer nouveau code secret"
+
+#: google-authenticator.php:251
+msgid "Show/Hide QR code"
+msgstr "Montrer/Cacher le QR Code"
+
+#: google-authenticator.php:259
+msgid "Scan this with the Google Authenticator app."
+msgstr "Scanner ceci avec votre app Google Authenticator"
+
+#: google-authenticator.php:264
+msgid "Enable App password"
+msgstr "Autoriser mot de passe de l'app"
+
+#: google-authenticator.php:266
+msgid " Enabling an App password will decrease your overall login security."
+msgstr ""
+"Autoriser un mot de passe d'app réduira votre sécurité globale de connexion."
+
+#: google-authenticator.php:274
+msgid "Create new password"
+msgstr "Créer nouveau mot de passe"
+
+#: google-authenticator.php:275
+msgid ""
+" Password is not stored in cleartext, this is your only chance to see it."
+msgstr ""
+"Le mot de passe n'est pas stocké en texte clair, c'est votre seule "
+"opportunité de le voir."
+
+#. Plugin Name of the plugin/theme
+msgid "Google Authenticator"
+msgstr "Google Authenticator"
+
+#. Plugin URI of the plugin/theme
+msgid "http://henrik.schack.dk/google-authenticator-for-wordpress";
+msgstr ""
+
+#. Description of the plugin/theme
+msgid ""
+"Two-Factor Authentication for WordPress using the Android/iPhone/Blackberry "
+"app as One Time Password generator."
+msgstr ""
+
+#. Author of the plugin/theme
+msgid "Henrik Schack"
+msgstr ""
+
+#. Author URI of the plugin/theme
+msgid "http://henrik.schack.dk/";
+msgstr ""

diff --git a/plugins/google-authenticator/lang/google-authenticator-it_IT.mo 
b/plugins/google-authenticator/lang/google-authenticator-it_IT.mo
new file mode 100644
index 0000000..dae99ae
Binary files /dev/null and 
b/plugins/google-authenticator/lang/google-authenticator-it_IT.mo differ

diff --git a/plugins/google-authenticator/lang/google-authenticator-it_IT.po 
b/plugins/google-authenticator/lang/google-authenticator-it_IT.po
new file mode 100644
index 0000000..361d581
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator-it_IT.po
@@ -0,0 +1,143 @@
+# Copyright (C) 2010 Google Authenticator
+# This file is distributed under the same license as the Google Authenticator 
package.
+# Aldo Latino <aldo...@gmail.com>, 2012, 2014.
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator 0.37\n"
+"Report-Msgid-Bugs-To: http://wordpress.org/tag/google-authenticator\n";
+"POT-Creation-Date: 2014-01-11 07:14:22+00:00\n"
+"PO-Revision-Date: 2014-01-12 21:24+0100\n"
+"Last-Translator: Aldo Latino <aldo...@gmail.com>\n"
+"Language-Team: Italian <kde-i18n...@kde.org>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 1.5\n"
+
+#: google-authenticator.php:166
+msgid ""
+"If you don't have Google Authenticator enabled for your WordPress account, "
+"leave this field empty."
+msgstr ""
+"Se Google Authenticator non è attivo per il tuo account WordPress, lascia "
+"vuoto questo campo."
+
+#: google-authenticator.php:166
+msgid "Google Authenticator code"
+msgstr "Codice di Google Authenticator"
+
+#: google-authenticator.php:231
+msgid "<strong>ERROR</strong>: The Google Authenticator password is incorrect."
+msgstr ""
+"<strong>ERRORE</strong>: la password di Google Authenticator non è corretta.."
+
+#: google-authenticator.php:234
+msgid ""
+"<strong>ERROR</strong>: The Google Authenticator code is incorrect or has "
+"expired."
+msgstr ""
+"<strong>ERRORE</strong>: Il codice di Google Authenticator non è corretto o "
+"è scaduto."
+
+#: google-authenticator.php:274
+msgid "WordPressBlog"
+msgstr "WordPress Blog"
+
+#: google-authenticator.php:277 google-authenticator.php:469
+msgid "Google Authenticator Settings"
+msgstr "Impostazioni di Google Authenticator"
+
+#: google-authenticator.php:282 google-authenticator.php:481
+msgid "Active"
+msgstr "Attivo"
+
+#: google-authenticator.php:290
+msgid "Relaxed mode"
+msgstr "Modalità comoda"
+
+#: google-authenticator.php:292
+msgid ""
+" Relaxed mode allows for more time drifting on your phone clock (&#177;4 "
+"min)."
+msgstr ""
+" La modalità comoda permette uno scostamento di tempo più esteso rispetto "
+"all'orologio del telefono (&#177;4 min)."
+
+#: google-authenticator.php:297
+msgid "Description"
+msgstr "Descrizione"
+
+#: google-authenticator.php:298
+msgid ""
+" Description that you'll see in the Google Authenticator app on your phone."
+msgstr ""
+" La descrizione che si vede nell'app Google Authenticator sul telefono."
+
+#: google-authenticator.php:302
+msgid "Secret"
+msgstr "Chiave segreta"
+
+#: google-authenticator.php:305
+msgid "Create new secret"
+msgstr "Crea una nuova chiave segreta"
+
+#: google-authenticator.php:306
+msgid "Show/Hide QR code"
+msgstr "Mostra/nascondi il codice QR"
+
+#: google-authenticator.php:315
+msgid "Scan this with the Google Authenticator app."
+msgstr "Effettua la scansione con l'app Google Authenticator."
+
+#: google-authenticator.php:320
+msgid "Enable App password"
+msgstr "Abilita la password delle App"
+
+#: google-authenticator.php:322
+msgid " Enabling an App password will decrease your overall login security."
+msgstr ""
+" L'abilitazione della password delle App abbasserà il livello di sicurezza "
+"generale del login."
+
+#: google-authenticator.php:330
+msgid "Create new password"
+msgstr "Crea una nuova password"
+
+#: google-authenticator.php:331
+msgid ""
+" Password is not stored in cleartext, this is your only chance to see it."
+msgstr ""
+" La password non è conservata in chiaro: questo l'unico momento in cui la si "
+"può vedere."
+
+#: google-authenticator.php:474
+msgid "Hide settings from user"
+msgstr "Nascondi le impostazioni agli utenti"
+
+#. Plugin Name of the plugin/theme
+msgid "Google Authenticator"
+msgstr "Google Authenticator"
+
+#. Plugin URI of the plugin/theme
+msgid "http://henrik.schack.dk/google-authenticator-for-wordpress";
+msgstr "http://henrik.schack.dk/google-authenticator-for-wordpress";
+
+#. Description of the plugin/theme
+msgid ""
+"Two-Factor Authentication for WordPress using the Android/iPhone/Blackberry "
+"app as One Time Password generator."
+msgstr ""
+"Autenticazione a due fattori per WordPress utilizzando un'app su Android/"
+"iPhone/Blackberry come generatore di Password usa-e-getta."
+
+#. Author of the plugin/theme
+msgid "Henrik Schack"
+msgstr "Henrik Schack"
+
+#. Author URI of the plugin/theme
+msgid "http://henrik.schack.dk/";
+msgstr "http://henrik.schack.dk/";
+
+

diff --git a/plugins/google-authenticator/lang/google-authenticator-zh_CN.mo 
b/plugins/google-authenticator/lang/google-authenticator-zh_CN.mo
new file mode 100644
index 0000000..cdf342e
Binary files /dev/null and 
b/plugins/google-authenticator/lang/google-authenticator-zh_CN.mo differ

diff --git a/plugins/google-authenticator/lang/google-authenticator-zh_CN.po 
b/plugins/google-authenticator/lang/google-authenticator-zh_CN.po
new file mode 100644
index 0000000..8b6cb67
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator-zh_CN.po
@@ -0,0 +1,126 @@
+# Copyright (C) 2010 Google Authenticator
+# This file is distributed under the same license as the Google Authenticator 
package.
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator 0.37\n"
+"Report-Msgid-Bugs-To: http://wordpress.org/tag/google-authenticator\n";
+"POT-Creation-Date: 2014-01-11 07:14:22+00:00\n"
+"PO-Revision-Date: 2014-01-13 13:48+0800\n"
+"Last-Translator: Kaijia Feng <fengkai...@gmail.com>\n"
+"Language-Team: \n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.5\n"
+
+#: google-authenticator.php:166
+msgid ""
+"If you don't have Google Authenticator enabled for your WordPress account, "
+"leave this field empty."
+msgstr "如果您的帐号没有启用Google Authenticator身份验证功能,请不必填写此栏。"
+
+#: google-authenticator.php:166
+msgid "Google Authenticator code"
+msgstr "Google Authenticator验证码"
+
+#: google-authenticator.php:231
+msgid "<strong>ERROR</strong>: The Google Authenticator password is incorrect."
+msgstr "<strong>错误</strong>:Google Authenticator验证码有误。"
+
+#: google-authenticator.php:234
+msgid ""
+"<strong>ERROR</strong>: The Google Authenticator code is incorrect or has "
+"expired."
+msgstr "<strong>错误</strong>:Google Authenticator验证码有误或者已经失效。"
+
+#: google-authenticator.php:274
+msgid "WordPressBlog"
+msgstr "WordPressBlog"
+
+#: google-authenticator.php:277 google-authenticator.php:469
+msgid "Google Authenticator Settings"
+msgstr "Google Authenticator设置"
+
+#: google-authenticator.php:282 google-authenticator.php:481
+msgid "Active"
+msgstr "启用"
+
+#: google-authenticator.php:290
+msgid "Relaxed mode"
+msgstr "宽松模式"
+
+#: google-authenticator.php:292
+msgid ""
+" Relaxed mode allows for more time drifting on your phone clock (&#177;4 "
+"min)."
+msgstr " 在宽松模式下你可以有更长的时间输入验证码(&#177;4分钟)。"
+
+#: google-authenticator.php:297
+msgid "Description"
+msgstr "描述"
+
+#: google-authenticator.php:298
+msgid ""
+" Description that you'll see in the Google Authenticator app on your phone."
+msgstr " 在Google Authenticator应用中显示的帐户描述。"
+
+#: google-authenticator.php:302
+msgid "Secret"
+msgstr "密钥"
+
+#: google-authenticator.php:305
+msgid "Create new secret"
+msgstr "创建新密钥"
+
+#: google-authenticator.php:306
+msgid "Show/Hide QR code"
+msgstr "显示/隐藏QR码"
+
+#: google-authenticator.php:315
+msgid "Scan this with the Google Authenticator app."
+msgstr "使用Google Authenticator应用扫描此图像。"
+
+#: google-authenticator.php:320
+msgid "Enable App password"
+msgstr "启用应用专用密码"
+
+#: google-authenticator.php:322
+msgid " Enabling an App password will decrease your overall login security."
+msgstr " 启用应用专用密码将会在总体上降低登录的安全性。"
+
+#: google-authenticator.php:330
+msgid "Create new password"
+msgstr "创建新密码"
+
+#: google-authenticator.php:331
+msgid ""
+" Password is not stored in cleartext, this is your only chance to see it."
+msgstr " 密码将不会明文储存,这将是你唯一一次看见密码。"
+
+#: google-authenticator.php:474
+msgid "Hide settings from user"
+msgstr "不对用户显示设置"
+
+#. Plugin Name of the plugin/theme
+msgid "Google Authenticator"
+msgstr "Google Authenticator"
+
+#. Plugin URI of the plugin/theme
+msgid "http://henrik.schack.dk/google-authenticator-for-wordpress";
+msgstr "http://henrik.schack.dk/google-authenticator-for-wordpress";
+
+#. Description of the plugin/theme
+msgid ""
+"Two-Factor Authentication for WordPress using the Android/iPhone/Blackberry "
+"app as One Time Password generator."
+msgstr ""
+"使用Android/iPhone/Blackberry一次性密码生成应用为WordPress提供两步验证。"
+
+#. Author of the plugin/theme
+msgid "Henrik Schack"
+msgstr "Henrik Schack"
+
+#. Author URI of the plugin/theme
+msgid "http://henrik.schack.dk/";
+msgstr "http://henrik.schack.dk/";

diff --git a/plugins/google-authenticator/lang/google-authenticator.pot 
b/plugins/google-authenticator/lang/google-authenticator.pot
new file mode 100644
index 0000000..c14d5c1
--- /dev/null
+++ b/plugins/google-authenticator/lang/google-authenticator.pot
@@ -0,0 +1,112 @@
+# Copyright (C) 2014 Google Authenticator
+# This file is distributed under the same license as the Google Authenticator 
package.
+msgid ""
+msgstr ""
+"Project-Id-Version: Google Authenticator 0.47\n"
+"Report-Msgid-Bugs-To: http://wordpress.org/tag/google-authenticator\n";
+"POT-Creation-Date: 2014-01-11 07:14:22+00:00\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <l...@li.org>\n"
+
+#: google-authenticator.php:166
+msgid "If you don't have Google Authenticator enabled for your WordPress 
account, leave this field empty."
+msgstr ""
+
+#: google-authenticator.php:166
+msgid "Google Authenticator code"
+msgstr ""
+
+#: google-authenticator.php:231
+msgid "<strong>ERROR</strong>: The Google Authenticator password is incorrect."
+msgstr ""
+
+#: google-authenticator.php:234
+msgid "<strong>ERROR</strong>: The Google Authenticator code is incorrect or 
has expired."
+msgstr ""
+
+#: google-authenticator.php:274
+msgid "WordPressBlog"
+msgstr ""
+
+#: google-authenticator.php:277 google-authenticator.php:469
+msgid "Google Authenticator Settings"
+msgstr ""
+
+#: google-authenticator.php:282 google-authenticator.php:481
+msgid "Active"
+msgstr ""
+
+#: google-authenticator.php:290
+msgid "Relaxed mode"
+msgstr ""
+
+#: google-authenticator.php:292
+msgid " Relaxed mode allows for more time drifting on your phone clock 
(&#177;4 min)."
+msgstr ""
+
+#: google-authenticator.php:297
+msgid "Description"
+msgstr ""
+
+#: google-authenticator.php:298
+msgid " Description that you'll see in the Google Authenticator app on your 
phone."
+msgstr ""
+
+#: google-authenticator.php:302
+msgid "Secret"
+msgstr ""
+
+#: google-authenticator.php:305
+msgid "Create new secret"
+msgstr ""
+
+#: google-authenticator.php:306
+msgid "Show/Hide QR code"
+msgstr ""
+
+#: google-authenticator.php:315
+msgid "Scan this with the Google Authenticator app."
+msgstr ""
+
+#: google-authenticator.php:320
+msgid "Enable App password"
+msgstr ""
+
+#: google-authenticator.php:322
+msgid " Enabling an App password will decrease your overall login security."
+msgstr ""
+
+#: google-authenticator.php:330
+msgid "Create new password"
+msgstr ""
+
+#: google-authenticator.php:331
+msgid " Password is not stored in cleartext, this is your only chance to see 
it."
+msgstr ""
+
+#: google-authenticator.php:474
+msgid "Hide settings from user"
+msgstr ""
+#. Plugin Name of the plugin/theme
+msgid "Google Authenticator"
+msgstr ""
+
+#. Plugin URI of the plugin/theme
+msgid "http://henrik.schack.dk/google-authenticator-for-wordpress";
+msgstr ""
+
+#. Description of the plugin/theme
+msgid "Two-Factor Authentication for WordPress using the 
Android/iPhone/Blackberry app as One Time Password generator."
+msgstr ""
+
+#. Author of the plugin/theme
+msgid "Henrik Schack"
+msgstr ""
+
+#. Author URI of the plugin/theme
+msgid "http://henrik.schack.dk/";
+msgstr ""

diff --git a/plugins/google-authenticator/readme.txt 
b/plugins/google-authenticator/readme.txt
new file mode 100644
index 0000000..865d784
--- /dev/null
+++ b/plugins/google-authenticator/readme.txt
@@ -0,0 +1,170 @@
+=== Google Authenticator ===
+Contributors: Henrik.Schack
+Donate Link: 
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=henrik%40schack%2edk&lc=US&item_name=Google%20Authenticator&item_number=Google%20Authenticator&no_shipping=0&no_note=1&tax=0&bn=PP%2dDonationsBF&charset=UTF%2d8
+Tags: authentication,otp,password,security,login,android,iphone,blackberry
+Requires at least: 4.5
+Tested up to: 4.7
+Stable tag: 0.48
+
+Google Authenticator for your WordPress blog.
+
+== Description ==
+
+The Google Authenticator plugin for WordPress gives you two-factor 
authentication using the Google Authenticator app for Android/iPhone/Blackberry.
+
+If you are security aware, you may already have the Google Authenticator app 
installed on your smartphone, using it for two-factor authentication on 
Gmail/Dropbox/Lastpass/Amazon etc.
+
+The two-factor authentication requirement can be enabled on a per-user basis. 
You could enable it for your administrator account, but log in as usual with 
less privileged accounts.
+
+If You need to maintain your blog using an Android/iPhone app, or any other 
software using the XMLRPC interface, you can enable the App password feature in 
this plugin, 
+but please note that enabling the App password feature will make your blog 
less secure.
+
+== Installation ==
+1. Make sure your webhost is capable of providing accurate time information 
for PHP/WordPress, ie. make sure a NTP daemon is running on the server.
+2. Install and activate the plugin.
+3. Enter a description on the Users -> Profile and Personal options page, in 
the Google Authenticator section.
+4. Scan the generated QR code with your phone, or enter the secret manually, 
remember to pick the time based one.  
+You may also want to write down the secret on a piece of paper and store it in 
a safe place. 
+5. Remember to hit the **Update profile** button at the bottom of the page 
before leaving the Personal options page.
+6. That's it, your WordPress blog is now a little more secure.
+
+== Frequently Asked Questions ==
+
+= Can I use Google Authenticator for WordPress with the Android/iPhone apps 
for WordPress? =
+
+Yes, you can enable the App password feature to make that possible, but notice 
that the XMLRPC interface isn't protected by two-factor authentication, only a 
long password.
+
+= I want to update the secret, should I just scan the new QR code after 
creating a new secret? =
+
+No, you'll have to delete the existing account from the Google Authenticator 
app on your smartphone before you scan the new QR code, that is unless you 
change the description as well.
+
+= I am unable to log in using this plugin, what's wrong ? =
+
+The Google Authenticator verification codes are time based, so it's crucial 
that the clock in your phone is accurate and in sync with the clock on the 
server where your WordPress installation is hosted.
+If you have an Android phone, you can use an app like 
[ClockSync](https://market.android.com/details?id=ru.org.amip.ClockSync) to set 
your clock in case your Cell provider doesn't provide accurate time information
+Another option is to enable "relaxed mode" in the settings for the plugin, 
this will enable more valid codes by allowing up to a 4 min. timedrift in each 
direction.
+
+= I have several users on my WordPress installation, is that a supported 
configuration ? =
+
+Yes, each user has his own Google Authenticator settings.
+
+= During installation I forgot the thing about making sure my webhost is 
capable of providing accurate time information, I'm now unable to login, please 
help. =
+
+If you have SSH or FTP access to your webhosting account, you can manually 
delete the plugin from your WordPress installation,
+just delete the wp-content/plugins/google-authenticator directory, and you'll 
be able to login using username/password again.
+
+= I don't own a Smartphone, isn't there another way to generate these secret 
codes ? =
+
+Yes, there is a webbased version here : http://gauth.apps.gbraad.nl/  
+Github project here : https://github.com/gbraad/html5-google-authenticator
+
+= Can I create backupcodes ? =
+
+No, but if you're using an Android smartphone you can replace the Google 
Authenticator app with [Authenticator 
Plus](https://play.google.com/store/apps/details?id=com.mufri.authenticatorplus).
  
+It's a really nice app that can import your existing settings, sync between 
devices and backup/restore using your sd-card.  
+It's not a free app, but it's well worth the money.
+
+= Any known incompatabilities ? =
+
+Yes, the Man-in-the-middle attack/replay detection code isn't compatible with 
the test/setup mode in the "Stop spammer registration plugin",
+please remember to remove the "Check credentials on all login attempts" 
checkmark before installing my plugin.
+
+
+
+== Screenshots ==
+
+1. The enhanced log-in box.
+2. Google Authenticator section on the Profile and Personal options page.
+3. QR code on the Profile and Personal options page.
+4. Google Authenticator app on Android
+
+== Changelog ==
+= 0.48 =
+* Security fix / compatability with WordPress 4.5
+
+= 0.47 =  
+* Google chart API replaced with jquery-qrcode
+* QR codes now contain a heading saying WordPress (Feature request by Flemming 
Mahler)
+* Danish translation & updated .pot file.
+* Plugin now logs login attempts recognized as Man-in-the-middle attacks.
+
+= 0.46 =  
+* Man-in-the-middle attack protection added.
+* Show warning before displaying the QR code.
+* FAQ updated.
+
+= 0.45 =  
+* Spaces in the description field should now work on iPhones.
+* Some depricated function calls replaced.
+* Code inputfield easier to use for .jp users now.
+* Sanitize description field input.
+* App password hash function switched to one that doesn't have rainbow tables 
available.
+* PHP notices occurring during app password login removed.
+
+
+= 0.44 =  
+* Installation/FAQ section updated.
+* Simplified Chinese translation by Kaijia Feng added. 
+* Tabindex on loginpage removed, no longer needed, was used by older WordPress 
installations.
+* Inputfield renamed to "googleotp".
+* Defaultdescription changed to "WordPressBlog" to avoid trouble for iPhone 
users.
+* Compatibility with Ryan Hellyer's plugin 
http://geek.ryanhellyer.net/products/deactivate-google-authenticator/
+* Must enter all 6 code digits.
+
+= 0.43 =  
+* It's now possible for an admin to hide the Google Authenticaator settings on 
a per-user basis. (Feature request by : Skate-O)
+
+= 0.42 =  
+* Autocomplete disabled on code input field. (Feature request by : hiphopsmurf)
+
+= 0.41 =  
+* Italian translation by Aldo Latino added.
+
+= 0.40 =  
+* Bugfix, typo corrected and PHP notices removed. Thanks to Dion Hulse for his 
patch.
+
+= 0.39 =  
+* Bugfix, Description was not saved to WordPress database when updating 
profile. Thanks to xxdesmus for noticing this.
+
+= 0.38 =  
+* Usability fix, input field for codes changed from password to text type.
+
+= 0.37 =  
+* The plugin now supports "relaxed mode" when authenticating. If selected, 
codes from 4 minutes before and 4 minutes after will work. 30 seconds before 
and after is still the default setting.
+
+= 0.36 =  
+* Bugfix, now an App password can only be used for XMLRPC/APP-Request logins.
+
+= 0.35 =  
+* Initial WordPress app support added (XMLRPC).
+
+= 0.30 =  
+* Code cleanup
+* Changed generation of secret key, to no longer have requirement of SHA256 on 
the server
+* German translation
+
+= 0.20 =  
+* Initial release
+
+
+== Credits ==
+
+Thanks to:
+
+[Tobias Bäthge](http://tobias.baethge.com/) for his code rewrite and German 
translation.
+
+[Pascal de Bruijn](http://blog.pcode.nl/) for his "relaxed mode" idea.
+
+[Daniel Werl](http://technobabbl.es/) for his usability tips.
+
+[Dion Hulse](http://dd32.id.au/) for his bugfixes.
+
+[Aldo Latino](http://profiles.wordpress.org/users/aldolat/) for his Italian 
translation.
+
+[Kaijia Feng](http://www.kaijia.me/) for his Simplified Chinese translation.
+
+[Alex Concha](http://www.buayacorp.com/) for his security tips.
+
+[Jerome Etienne](http://jetienne.com/) for his jquery-qrcode plugin.
+
+[Sébastien Prunier](http://orizhial.com/) for his Spanish and French 
translation.

diff --git a/plugins/google-authenticator/screenshot-1.jpg 
b/plugins/google-authenticator/screenshot-1.jpg
new file mode 100644
index 0000000..252831f
Binary files /dev/null and b/plugins/google-authenticator/screenshot-1.jpg 
differ

diff --git a/plugins/google-authenticator/screenshot-2.jpg 
b/plugins/google-authenticator/screenshot-2.jpg
new file mode 100644
index 0000000..13bb25c
Binary files /dev/null and b/plugins/google-authenticator/screenshot-2.jpg 
differ

diff --git a/plugins/google-authenticator/screenshot-3.jpg 
b/plugins/google-authenticator/screenshot-3.jpg
new file mode 100644
index 0000000..b74aeae
Binary files /dev/null and b/plugins/google-authenticator/screenshot-3.jpg 
differ

diff --git a/plugins/google-authenticator/screenshot-4.jpg 
b/plugins/google-authenticator/screenshot-4.jpg
new file mode 100644
index 0000000..804f3ca
Binary files /dev/null and b/plugins/google-authenticator/screenshot-4.jpg 
differ

diff --git a/plugins/google-authenticator/screenshot-5.jpg 
b/plugins/google-authenticator/screenshot-5.jpg
new file mode 100644
index 0000000..1b39629
Binary files /dev/null and b/plugins/google-authenticator/screenshot-5.jpg 
differ

Reply via email to