Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Commit 4bee7ab

Browse files
committed
PERL-884 Update SCRAM-SHA-256 implementation
This commit removes SASLprep for usernames, in accordance with the updated MongoDB Auth spec https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
1 parent 53ede8c commit 4bee7ab

File tree

3 files changed

+50
-38
lines changed

3 files changed

+50
-38
lines changed

devel/config/mongod-4.0-scram.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
type: single
33
default_args: -v --bind_ip 0.0.0.0
4-
default_version: v3.7.2
4+
default_version: v3.7.6
55
default_fcv: "4.0"
66
auth:
77
user: root

devel/t-dynamic/AUTH-SCRAM-4.0.t

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use boolean;
2626

2727
use MongoDB;
2828
use MongoDB::Error;
29-
use Authen::SASL::SASLprep qw/saslprep/;
3029

3130
use lib "t/lib";
3231
use lib "devel/lib";
@@ -97,7 +96,8 @@ $ENV{MONGOD} = $orc->as_uri;
9796

9897
my $uri = MongoDB::_URI->new( uri => $ENV{MONGOD} );
9998
my $no_auth_string = "mongodb://" . $uri->hostids->[0];
100-
my $unprepped_string = "\x{2168}"; # ROMAN NUMERAL NINE -> prepped is "IX"
99+
my $roman_four = "\x{2163}"; # ROMAN NUMERAL FOUR -> prepped is "IV"
100+
my $roman_nine = "\x{2168}"; # ROMAN NUMERAL NINE -> prepped is "IX"
101101
my $admin_client = build_client();
102102
my $testdb = get_test_db($admin_client);
103103

@@ -113,14 +113,18 @@ sub _options_to_uri {
113113
}
114114

115115
my %users = (
116-
sha1 => [ 'pwd', ['SCRAM-SHA-1'] ],
117-
$unprepped_string => [ $unprepped_string, ['SCRAM-SHA-256'] ],
118-
both => [ 'pwd', [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ] ],
116+
# Test steps 1-3
117+
sha1 => [ 'sha1', ['SCRAM-SHA-1'] ],
118+
sha256 => [ 'sha256', ['SCRAM-SHA-256'] ],
119+
both => [ 'both', [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ] ],
120+
# Test step 4 ( extra array ref are alternate passwd forms )
121+
IX => [ 'IX', ['SCRAM-SHA-256'], ["I\x{00AD}X"] ],
122+
$roman_nine => [ $roman_four, ['SCRAM-SHA-256'], ["I\x{00AD}V"] ],
119123
);
120124

121125
for my $user ( sort keys %users ) {
122-
my ( $pwd, $mechs ) = @{ $users{$user} };
123-
create_user( $testdb, saslprep($user), $pwd, $mechs );
126+
my ( $pwd, $mechs, undef ) = @{ $users{$user} };
127+
create_user( $testdb, $user, $pwd, $mechs );
124128
}
125129

126130
subtest "no authentication" => sub {
@@ -152,36 +156,42 @@ subtest "invalid user" => sub {
152156
};
153157

154158
for my $user ( sort keys %users ) {
155-
subtest "auth user $user" => sub {
156-
my @options = (
157-
host => $no_auth_string,
158-
username => $user,
159-
password => $users{$user}[0],
160-
db_name => $testdb->name,
161-
dt_type => undef,
162-
);
163-
164-
my $user_has_mech = { map { $_ => 1 } @{ $users{$user}[1] } };
165-
166-
# auth with explicit mechanisms
167-
for my $mech (qw/SCRAM-SHA-1 SCRAM-SHA-256/) {
168-
if ( $user_has_mech->{$mech} ) {
169-
auth_ok( "auth via $mech", $testdb->name, @options, auth_mechanism => $mech );
170-
is( $scram_args[-1], $mech, "correct internal call for $mech" );
159+
my @pwds = ( $users{$user}[0] );
160+
push @pwds, @{$users{$user}[2]}
161+
if $users{$user}[2];
162+
163+
for my $pass ( @pwds ) {
164+
subtest "auth user $user, pwd $pass" => sub {
165+
my @options = (
166+
host => $no_auth_string,
167+
username => $user,
168+
password => $pass,
169+
db_name => $testdb->name,
170+
dt_type => undef,
171+
);
172+
173+
my $user_has_mech = { map { $_ => 1 } @{ $users{$user}[1] } };
174+
175+
# auth with explicit mechanisms
176+
for my $mech (qw/SCRAM-SHA-1 SCRAM-SHA-256/) {
177+
if ( $user_has_mech->{$mech} ) {
178+
auth_ok( "auth via $mech", $testdb->name, @options, auth_mechanism => $mech );
179+
is( $scram_args[-1], $mech, "correct internal call for $mech" );
180+
}
181+
else {
182+
auth_not_ok( "auth via $mech", $testdb->name, @options, auth_mechanism => $mech );
183+
}
171184
}
172-
else {
173-
auth_not_ok( "auth via $mech", $testdb->name, @options, auth_mechanism => $mech );
174-
}
175-
}
176-
177-
# auth with negotiation
178-
auth_ok( "auth via negotiation", $testdb->name, @options );
179-
my $expected_mech =
180-
( grep { $_ eq 'SCRAM-SHA-256' } @{ $users{$user}[1] } )
181-
? 'SCRAM-SHA-256'
182-
: 'SCRAM-SHA-1';
183-
is( $scram_args[-1], $expected_mech, "correct internal call for negotiated mech" );
184-
};
185+
186+
# auth with negotiation
187+
auth_ok( "auth via negotiation", $testdb->name, @options );
188+
my $expected_mech =
189+
( grep { $_ eq 'SCRAM-SHA-256' } @{ $users{$user}[1] } )
190+
? 'SCRAM-SHA-256'
191+
: 'SCRAM-SHA-1';
192+
is( $scram_args[-1], $expected_mech, "correct internal call for negotiated mech" );
193+
};
194+
}
185195
}
186196

187197
clear_testdbs;

lib/MongoDB/_Credential.pm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,13 @@ sub _build__scram_sha256_client {
129129
# modules
130130
require Authen::SCRAM::Client;
131131
Authen::SCRAM::Client->VERSION(0.007);
132+
require Authen::SASL::SASLprep;
132133
return Authen::SCRAM::Client->new(
133134
username => $self->username,
134-
password => $self->password,
135+
password => Authen::SASL::SASLprep::saslprep($self->password),
135136
digest => 'SHA-256',
136137
minimum_iteration_count => 4096,
138+
skip_saslprep => 1,
137139
);
138140
}
139141

0 commit comments

Comments
 (0)