From 05fed61671067cb6a750d41909ccb5692ba43808 Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Tue, 29 Sep 2015 22:57:02 +0800 Subject: Bug 1199090 - add printable recovery 2fa codes --- Bugzilla/MFA.pm | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'Bugzilla/MFA.pm') 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); -- cgit v1.2.3-24-g4f1b