Two-Factor - Version 0.7.1

Version Description

Download this release

Release Info

Developer kasparsd
Plugin Icon 128x128 Two-Factor
Version 0.7.1
Comparing to
See all releases

Code changes from version 0.7.2 to 0.7.1

class-two-factor-core.php CHANGED
@@ -550,7 +550,7 @@ class Two_Factor_Core {
550
  }
551
 
552
  if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
553
- wp_safe_redirect( home_url() );
554
  exit;
555
  }
556
 
@@ -680,34 +680,34 @@ class Two_Factor_Core {
680
  </div>
681
  <?php endif; ?>
682
  <style>
683
- /* @todo: migrate to an external stylesheet. */
684
- .backup-methods-wrap {
685
  margin-top: 16px;
686
  padding: 0 24px;
687
- }
688
- .backup-methods-wrap a {
689
  color: #999;
690
  text-decoration: none;
691
- }
692
- ul.backup-methods {
693
  display: none;
694
  padding-left: 1.5em;
695
- }
696
- /* Prevent Jetpack from hiding our controls, see https://github.com/Automattic/jetpack/issues/3747 */
697
- .jetpack-sso-form-display #loginform > p,
698
- .jetpack-sso-form-display #loginform > div {
699
  display: block;
700
- }
701
  </style>
702
 
703
  <?php
704
- if ( ! function_exists( 'login_footer' ) ) {
705
- include_once TWO_FACTOR_DIR . 'includes/function.login-footer.php';
706
- }
707
 
708
  login_footer();
709
  ?>
710
- <?php
711
  }
712
 
713
  /**
@@ -728,17 +728,6 @@ class Two_Factor_Core {
728
  return add_query_arg( $params, site_url( 'wp-login.php', $scheme ) );
729
  }
730
 
731
- /**
732
- * Get the hash of a nonce for storage and comparison.
733
- *
734
- * @param string $nonce Nonce value to be hashed.
735
- *
736
- * @return string
737
- */
738
- protected static function hash_login_nonce( $nonce ) {
739
- return wp_hash( $nonce, 'nonce' );
740
- }
741
-
742
  /**
743
  * Create the login nonce.
744
  *
@@ -748,21 +737,15 @@ class Two_Factor_Core {
748
  * @return array
749
  */
750
  public static function create_login_nonce( $user_id ) {
751
- $login_nonce = array(
752
- 'expiration' => time() + HOUR_IN_SECONDS,
753
- );
754
-
755
  try {
756
  $login_nonce['key'] = bin2hex( random_bytes( 32 ) );
757
  } catch ( Exception $ex ) {
758
  $login_nonce['key'] = wp_hash( $user_id . wp_rand() . microtime(), 'nonce' );
759
  }
 
760
 
761
- // Store the nonce hashed to avoid leaking it via database access.
762
- $login_nonce_stored = $login_nonce;
763
- $login_nonce_stored['key'] = self::hash_login_nonce( $login_nonce['key'] );
764
-
765
- if ( ! update_user_meta( $user_id, self::USER_META_NONCE_KEY, $login_nonce_stored ) ) {
766
  return false;
767
  }
768
 
@@ -792,19 +775,16 @@ class Two_Factor_Core {
792
  */
793
  public static function verify_login_nonce( $user_id, $nonce ) {
794
  $login_nonce = get_user_meta( $user_id, self::USER_META_NONCE_KEY, true );
795
-
796
- if ( ! $login_nonce || empty( $login_nonce['key'] ) || empty( $login_nonce['expiration'] ) ) {
797
  return false;
798
  }
799
 
800
- if ( hash_equals( $login_nonce['key'], self::hash_login_nonce( $nonce ) ) && time() < $login_nonce['expiration'] ) {
801
- return true;
 
802
  }
803
 
804
- // Require a fresh nonce if verification fails.
805
- self::delete_login_nonce( $user_id );
806
-
807
- return false;
808
  }
809
 
810
  /**
@@ -826,7 +806,7 @@ class Two_Factor_Core {
826
  }
827
 
828
  if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
829
- wp_safe_redirect( home_url() );
830
  exit;
831
  }
832
 
@@ -999,7 +979,7 @@ class Two_Factor_Core {
999
  *
1000
  * @param WP_User $user The user.
1001
  */
1002
- do_action_deprecated( 'two-factor-user-options-' . $class, array( $user ), '0.7.0', 'two_factor_user_options_' . $class );
1003
  do_action( 'two_factor_user_options_' . $class, $user );
1004
  ?>
1005
  </td>
550
  }
551
 
552
  if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
553
+ wp_safe_redirect( get_bloginfo( 'url' ) );
554
  exit;
555
  }
556
 
680
  </div>
681
  <?php endif; ?>
682
  <style>
683
+ /* @todo: migrate to an external stylesheet. */
684
+ .backup-methods-wrap {
685
  margin-top: 16px;
686
  padding: 0 24px;
687
+ }
688
+ .backup-methods-wrap a {
689
  color: #999;
690
  text-decoration: none;
691
+ }
692
+ ul.backup-methods {
693
  display: none;
694
  padding-left: 1.5em;
695
+ }
696
+ /* Prevent Jetpack from hiding our controls, see https://github.com/Automattic/jetpack/issues/3747 */
697
+ .jetpack-sso-form-display #loginform > p,
698
+ .jetpack-sso-form-display #loginform > div {
699
  display: block;
700
+ }
701
  </style>
702
 
703
  <?php
704
+ if ( ! function_exists( 'login_footer' ) ) {
705
+ include_once TWO_FACTOR_DIR . 'includes/function.login-footer.php';
706
+ }
707
 
708
  login_footer();
709
  ?>
710
+ <?php
711
  }
712
 
713
  /**
728
  return add_query_arg( $params, site_url( 'wp-login.php', $scheme ) );
729
  }
730
 
 
 
 
 
 
 
 
 
 
 
 
731
  /**
732
  * Create the login nonce.
733
  *
737
  * @return array
738
  */
739
  public static function create_login_nonce( $user_id ) {
740
+ $login_nonce = array();
 
 
 
741
  try {
742
  $login_nonce['key'] = bin2hex( random_bytes( 32 ) );
743
  } catch ( Exception $ex ) {
744
  $login_nonce['key'] = wp_hash( $user_id . wp_rand() . microtime(), 'nonce' );
745
  }
746
+ $login_nonce['expiration'] = time() + HOUR_IN_SECONDS;
747
 
748
+ if ( ! update_user_meta( $user_id, self::USER_META_NONCE_KEY, $login_nonce ) ) {
 
 
 
 
749
  return false;
750
  }
751
 
775
  */
776
  public static function verify_login_nonce( $user_id, $nonce ) {
777
  $login_nonce = get_user_meta( $user_id, self::USER_META_NONCE_KEY, true );
778
+ if ( ! $login_nonce ) {
 
779
  return false;
780
  }
781
 
782
+ if ( $nonce !== $login_nonce['key'] || time() > $login_nonce['expiration'] ) {
783
+ self::delete_login_nonce( $user_id );
784
+ return false;
785
  }
786
 
787
+ return true;
 
 
 
788
  }
789
 
790
  /**
806
  }
807
 
808
  if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
809
+ wp_safe_redirect( get_bloginfo( 'url' ) );
810
  exit;
811
  }
812
 
979
  *
980
  * @param WP_User $user The user.
981
  */
982
+ do_action_deprecated( 'two-factor-user-options-' . $class, array( $user ), '0.7.0', 'two_factor_user_options_' . $class );
983
  do_action( 'two_factor_user_options_' . $class, $user );
984
  ?>
985
  </td>
providers/class-two-factor-email.php CHANGED
@@ -187,7 +187,7 @@ class Two_Factor_Email extends Two_Factor_Provider {
187
  $hashed_token = $this->get_user_token( $user_id );
188
 
189
  // Bail if token is empty or it doesn't match.
190
- if ( empty( $hashed_token ) || ! hash_equals( wp_hash( $token ), $hashed_token ) ) {
191
  return false;
192
  }
193
 
@@ -224,7 +224,7 @@ class Two_Factor_Email extends Two_Factor_Provider {
224
  $token = $this->generate_token( $user->ID );
225
 
226
  /* translators: %s: site name */
227
- $subject = wp_strip_all_tags( sprintf( __( 'Your login confirmation code for %s', 'two-factor' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ) );
228
  /* translators: %s: token */
229
  $message = wp_strip_all_tags( sprintf( __( 'Enter %s to log in.', 'two-factor' ), $token ) );
230
 
@@ -245,7 +245,7 @@ class Two_Factor_Email extends Two_Factor_Provider {
245
  */
246
  $message = apply_filters( 'two_factor_token_email_message', $message, $token, $user->ID );
247
 
248
- return wp_mail( $user->user_email, $subject, $message ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_mail_wp_mail
249
  }
250
 
251
  /**
187
  $hashed_token = $this->get_user_token( $user_id );
188
 
189
  // Bail if token is empty or it doesn't match.
190
+ if ( empty( $hashed_token ) || ( wp_hash( $token ) !== $hashed_token ) ) {
191
  return false;
192
  }
193
 
224
  $token = $this->generate_token( $user->ID );
225
 
226
  /* translators: %s: site name */
227
+ $subject = wp_strip_all_tags( sprintf( __( 'Your login confirmation code for %s', 'two-factor' ), get_bloginfo( 'name' ) ) );
228
  /* translators: %s: token */
229
  $message = wp_strip_all_tags( sprintf( __( 'Enter %s to log in.', 'two-factor' ), $token ) );
230
 
245
  */
246
  $message = apply_filters( 'two_factor_token_email_message', $message, $token, $user->ID );
247
 
248
+ return wp_mail( $user->user_email, $subject, $message );
249
  }
250
 
251
  /**
providers/class-two-factor-fido-u2f-admin.php CHANGED
@@ -281,7 +281,6 @@ class Two_Factor_FIDO_U2F_Admin {
281
  Two_Factor_FIDO_U2F::delete_security_key( $user_id, $slug );
282
 
283
  wp_safe_redirect( remove_query_arg( 'new_app_pass', wp_get_referer() ) . '#security-keys-section' );
284
- exit;
285
  }
286
  }
287
 
281
  Two_Factor_FIDO_U2F::delete_security_key( $user_id, $slug );
282
 
283
  wp_safe_redirect( remove_query_arg( 'new_app_pass', wp_get_referer() ) . '#security-keys-section' );
 
284
  }
285
  }
286
 
providers/class-two-factor-totp.php CHANGED
@@ -361,7 +361,7 @@ class Two_Factor_Totp extends Two_Factor_Provider {
361
  if ( PHP_INT_SIZE >= 8 ) {
362
  // If we're on PHP 5.6.3+ we can use the new 64bit pack functionality.
363
  if ( version_compare( PHP_VERSION, '5.6.3', '>=' ) && PHP_INT_SIZE >= 8 ) {
364
- return pack( 'J', $value ); // phpcs:ignore PHPCompatibility.ParameterValues.NewPackFormat.NewFormatFound
365
  }
366
  $highmap = 0xffffffff << 32;
367
  $higher = ( $value & $highmap ) >> 32;
361
  if ( PHP_INT_SIZE >= 8 ) {
362
  // If we're on PHP 5.6.3+ we can use the new 64bit pack functionality.
363
  if ( version_compare( PHP_VERSION, '5.6.3', '>=' ) && PHP_INT_SIZE >= 8 ) {
364
+ return pack( 'J', $value );
365
  }
366
  $highmap = 0xffffffff << 32;
367
  $higher = ( $value & $highmap ) >> 32;
providers/css/fido-u2f-admin.css CHANGED
@@ -1,11 +1,9 @@
1
  #security-keys-section .wp-list-table {
2
  margin-bottom: 2em;
3
  }
4
-
5
  #security-keys-section .register-security-key .spinner {
6
  float: none;
7
  }
8
-
9
  #security-keys-section .security-key-status {
10
  vertical-align: middle;
11
  font-style: italic;
1
  #security-keys-section .wp-list-table {
2
  margin-bottom: 2em;
3
  }
 
4
  #security-keys-section .register-security-key .spinner {
5
  float: none;
6
  }
 
7
  #security-keys-section .security-key-status {
8
  vertical-align: middle;
9
  font-style: italic;
providers/js/fido-u2f-admin-inline-edit.js CHANGED
@@ -1,4 +1,4 @@
1
- /* global window, document, jQuery, inlineEditL10n, ajaxurl */
2
  var inlineEditKey;
3
 
4
  ( function( $ ) {
@@ -39,12 +39,7 @@ var inlineEditKey;
39
 
40
  toggle: function( el ) {
41
  var t = this;
42
-
43
- if ( 'none' === $( t.what + t.getId( el ) ).css( 'display' ) ) {
44
- t.revert();
45
- } else {
46
- t.edit( el );
47
- }
48
  },
49
 
50
  edit: function( id ) {
@@ -56,9 +51,7 @@ var inlineEditKey;
56
  id = t.getId( id );
57
  }
58
 
59
- editRow = $( '#inline-edit' ).clone( true );
60
- rowData = $( '#inline_' + id );
61
-
62
  $( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '#security-keys-section .widefat thead' ).length );
63
 
64
  $( t.what + id ).hide().after( editRow ).after( '<tr class="hidden"></tr>' );
@@ -97,7 +90,7 @@ var inlineEditKey;
97
  // Make ajax request.
98
  $.post( ajaxurl, params,
99
  function( r ) {
100
- var row, newID;
101
  $( '#security-keys-section table.widefat .spinner' ).removeClass( 'is-active' );
102
 
103
  if ( r ) {
@@ -108,8 +101,10 @@ var inlineEditKey;
108
  $( '#edit-' + id ).before( r ).remove();
109
 
110
  if ( newID ) {
 
111
  row = $( '#' + newID );
112
  } else {
 
113
  row = $( inlineEditKey.what + id );
114
  }
115
 
@@ -147,4 +142,5 @@ var inlineEditKey;
147
  $( document ).ready( function() {
148
  inlineEditKey.init();
149
  } );
150
- }( jQuery ) );
 
1
+ /* global inlineEditL10n, ajaxurl */
2
  var inlineEditKey;
3
 
4
  ( function( $ ) {
39
 
40
  toggle: function( el ) {
41
  var t = this;
42
+ 'none' === $( t.what + t.getId( el ) ).css( 'display' ) ? t.revert() : t.edit( el );
 
 
 
 
 
43
  },
44
 
45
  edit: function( id ) {
51
  id = t.getId( id );
52
  }
53
 
54
+ editRow = $( '#inline-edit' ).clone( true ), rowData = $( '#inline_' + id );
 
 
55
  $( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '#security-keys-section .widefat thead' ).length );
56
 
57
  $( t.what + id ).hide().after( editRow ).after( '<tr class="hidden"></tr>' );
90
  // Make ajax request.
91
  $.post( ajaxurl, params,
92
  function( r ) {
93
+ var row, newID, optionValue;
94
  $( '#security-keys-section table.widefat .spinner' ).removeClass( 'is-active' );
95
 
96
  if ( r ) {
101
  $( '#edit-' + id ).before( r ).remove();
102
 
103
  if ( newID ) {
104
+ optionValue = newID.replace( 'key-', '' );
105
  row = $( '#' + newID );
106
  } else {
107
+ optionValue = id;
108
  row = $( inlineEditKey.what + id );
109
  }
110
 
142
  $( document ).ready( function() {
143
  inlineEditKey.init();
144
  } );
145
+
146
+ } )( jQuery );
providers/js/fido-u2f-admin.js CHANGED
@@ -1,4 +1,4 @@
1
- /* global window, u2fL10n, jQuery */
2
  ( function( $ ) {
3
  var $button = $( '#register_security_key' );
4
  var $statusNotice = $( '#security-keys-section .security-key-status' );
@@ -45,4 +45,4 @@
45
  $( '<form>' )[0].submit.call( $( '#your-profile' )[0] );
46
  } );
47
  } );
48
- }( jQuery ) );
1
+ /* global u2f, u2fL10n */
2
  ( function( $ ) {
3
  var $button = $( '#register_security_key' );
4
  var $statusNotice = $( '#security-keys-section .security-key-status' );
45
  $( '<form>' )[0].submit.call( $( '#your-profile' )[0] );
46
  } );
47
  } );
48
+ } )( jQuery );
providers/js/fido-u2f-login.js CHANGED
@@ -1,4 +1,4 @@
1
- /* global window, u2f, u2fL10n, jQuery */
2
  ( function( $ ) {
3
  if ( ! window.u2fL10n ) {
4
  window.console.error( 'u2fL10n is not defined' );
@@ -13,4 +13,4 @@
13
  $( '#loginform' ).submit();
14
  }
15
  } );
16
- }( jQuery ) );
1
+ /* global u2f, u2fL10n */
2
  ( function( $ ) {
3
  if ( ! window.u2fL10n ) {
4
  window.console.error( 'u2fL10n is not defined' );
13
  $( '#loginform' ).submit();
14
  }
15
  } );
16
+ } )( jQuery );
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: georgestephanis, valendesigns, stevenkword, extendwings, sgrant, aaroncampbell, johnbillion, stevegrunwell, netweb, kasparsd, alihusnainarshad, passoniate
3
  Tags: two factor, two step, authentication, login, totp, fido u2f, u2f, email, backup codes, 2fa, yubikey
4
  Requires at least: 4.3
5
- Tested up to: 6.0
6
  Requires PHP: 5.6
7
  Stable tag: trunk
8
 
@@ -37,7 +37,14 @@ Here is a list of action and filter hooks provided by the plugin:
37
 
38
  == Get Involved ==
39
 
40
- Development happens [on GitHub](https://github.com/wordpress/two-factor/).
 
 
 
 
 
 
 
41
 
42
  == Changelog ==
43
 
2
  Contributors: georgestephanis, valendesigns, stevenkword, extendwings, sgrant, aaroncampbell, johnbillion, stevegrunwell, netweb, kasparsd, alihusnainarshad, passoniate
3
  Tags: two factor, two step, authentication, login, totp, fido u2f, u2f, email, backup codes, 2fa, yubikey
4
  Requires at least: 4.3
5
+ Tested up to: 5.8
6
  Requires PHP: 5.6
7
  Stable tag: trunk
8
 
37
 
38
  == Get Involved ==
39
 
40
+ Development happens [on GitHub](https://github.com/wordpress/two-factor/). Join the `#core-passwords` channel [on WordPress Slack](http://wordpress.slack.com) ([sign up here](http://chat.wordpress.org)).
41
+
42
+ Here is how to get started:
43
+
44
+ $ git clone https://github.com/wordpress/two-factor.git
45
+ $ npm install
46
+
47
+ Then open [a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) with the suggested changes.
48
 
49
  == Changelog ==
50
 
two-factor.php CHANGED
@@ -12,7 +12,7 @@
12
  * Plugin URI: https://wordpress.org/plugins/two-factor/
13
  * Description: Two-Factor Authentication using time-based one-time passwords, Universal 2nd Factor (FIDO U2F), email and backup verification codes.
14
  * Author: Plugin Contributors
15
- * Version: 0.7.2
16
  * Author URI: https://github.com/wordpress/two-factor/graphs/contributors
17
  * Network: True
18
  * Text Domain: two-factor
@@ -26,7 +26,7 @@ define( 'TWO_FACTOR_DIR', plugin_dir_path( __FILE__ ) );
26
  /**
27
  * Version of the plugin.
28
  */
29
- define( 'TWO_FACTOR_VERSION', '0.7.2' );
30
 
31
  /**
32
  * Include the base class here, so that other plugins can also extend it.
12
  * Plugin URI: https://wordpress.org/plugins/two-factor/
13
  * Description: Two-Factor Authentication using time-based one-time passwords, Universal 2nd Factor (FIDO U2F), email and backup verification codes.
14
  * Author: Plugin Contributors
15
+ * Version: 0.7.1
16
  * Author URI: https://github.com/wordpress/two-factor/graphs/contributors
17
  * Network: True
18
  * Text Domain: two-factor
26
  /**
27
  * Version of the plugin.
28
  */
29
+ define( 'TWO_FACTOR_VERSION', '0.7.1' );
30
 
31
  /**
32
  * Include the base class here, so that other plugins can also extend it.
user-edit.css CHANGED
@@ -34,4 +34,4 @@
34
 
35
  .two-factor-methods-table tbody tr:nth-child(odd) {
36
  background-color: #f9f9f9;
37
- }
34
 
35
  .two-factor-methods-table tbody tr:nth-child(odd) {
36
  background-color: #f9f9f9;
37
+ }