summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2015-09-29 16:57:02 +0200
committerByron Jones <glob@mozilla.com>2015-09-29 16:57:02 +0200
commit05fed61671067cb6a750d41909ccb5692ba43808 (patch)
tree3ed5654e9383df29b48c009f16aed40d26782b1d /Bugzilla
parent87c32cbdf12784dacbbcd9694753ac0e5e02afea (diff)
downloadbugzilla-05fed61671067cb6a750d41909ccb5692ba43808.tar.gz
bugzilla-05fed61671067cb6a750d41909ccb5692ba43808.tar.xz
Bug 1199090 - add printable recovery 2fa codes
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Auth.pm4
-rw-r--r--Bugzilla/MFA.pm50
-rw-r--r--Bugzilla/MFA/TOTP.pm4
3 files changed, 51 insertions, 7 deletions
diff --git a/Bugzilla/Auth.pm b/Bugzilla/Auth.pm
index b39bb827b..50e892914 100644
--- a/Bugzilla/Auth.pm
+++ b/Bugzilla/Auth.pm
@@ -133,8 +133,8 @@ sub mfa_verified {
my $params = Bugzilla->input_params;
$self->{_info_getter}->{successful} = Bugzilla::Auth::Login::CGI->new();
- $params->{Bugzilla_restrictlogin} = $event->{restrictlogin};
- $params->{Bugzilla_remember} = $event->{remember};
+ $params->{Bugzilla_restrictlogin} = !!$event->{restrictlogin};
+ $params->{Bugzilla_remember} = !!$event->{remember};
$self->_handle_login_result({ user => $user }, $event->{type});
}
diff --git a/Bugzilla/MFA.pm b/Bugzilla/MFA.pm
index 21f42fbfb..4f0d8a547 100644
--- a/Bugzilla/MFA.pm
+++ b/Bugzilla/MFA.pm
@@ -8,7 +8,9 @@
package Bugzilla::MFA;
use strict;
+use Bugzilla::RNG qw( irand );
use Bugzilla::Token qw( issue_short_lived_session_token set_token_extra_data get_token_extra_data delete_token );
+use Bugzilla::Util qw( trick_taint);
sub new {
my ($class, $user) = @_;
@@ -46,15 +48,15 @@ sub verify_prompt {
exit;
}
-sub verify_check {
+sub verify_token {
my ($self, $token) = @_;
# check token
my ($user_id) = Bugzilla::Token::GetTokenData($token);
my $user = Bugzilla::User->check({ id => $user_id, cache => 1 });
- # mfa verification
- $self->check(Bugzilla->input_params);
+ # verify mfa
+ $self->verify_check(Bugzilla->input_params);
# return event data
my $event = get_token_extra_data($token);
@@ -66,10 +68,49 @@ sub verify_check {
return $event;
}
+sub verify_check {
+ my ($self, $params) = @_;
+ $params->{code} //= '';
+
+ # recovery code verification
+ if (length($params->{code}) == 9) {
+ my $code = $params->{code};
+ foreach my $i (1..10) {
+ my $key = "recovery.$i";
+ if (($self->property_get($key) // '') eq $code) {
+ $self->property_delete($key);
+ return;
+ }
+ }
+ }
+
+ # mfa verification
+ $self->check($params);
+}
+
+# methods
+
+sub generate_recovery_codes {
+ my ($self) = @_;
+
+ my @codes;
+ foreach my $i (1..10) {
+ # generate 9 digit code
+ my $code;
+ $code .= irand(10) for 1..9;
+ push @codes, $code;
+ # store (replacing existing)
+ $self->property_set("recovery.$i", $code);
+ }
+
+ return \@codes;
+}
+
# helpers
sub property_get {
my ($self, $name) = @_;
+ trick_taint($name);
return scalar Bugzilla->dbh->selectrow_array(
"SELECT value FROM profile_mfa WHERE user_id = ? AND name = ?",
undef, $self->{user}->id, $name);
@@ -77,6 +118,8 @@ sub property_get {
sub property_set {
my ($self, $name, $value) = @_;
+ trick_taint($name);
+ trick_taint($value);
Bugzilla->dbh->do(
"INSERT INTO profile_mfa (user_id, name, value) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE value = ?",
undef, $self->{user}->id, $name, $value, $value);
@@ -84,6 +127,7 @@ sub property_set {
sub property_delete {
my ($self, $name) = @_;
+ trick_taint($name);
Bugzilla->dbh->do(
"DELETE FROM profile_mfa WHERE user_id = ? AND name = ?",
undef, $self->{user}->id, $name);
diff --git a/Bugzilla/MFA/TOTP.pm b/Bugzilla/MFA/TOTP.pm
index 859ca4b8d..64efcfc8d 100644
--- a/Bugzilla/MFA/TOTP.pm
+++ b/Bugzilla/MFA/TOTP.pm
@@ -58,10 +58,10 @@ sub prompt {
sub check {
my ($self, $params) = @_;
- my $code = $params->{code} // '';
+ my $code = $params->{code};
return if $self->_auth()->verify($code, 1);
- if (exists $params->{mfa_action}) {
+ if ($params->{mfa_action} && $params->{mfa_action} eq 'enable') {
ThrowUserError('mfa_totp_bad_enrolment_code');
}
else {