%PDF- %PDF-
Direktori : /home/opti/optisoftcom/.cpanm/work/1544535425.21555/Authen-SCRAM-0.011/devel/ |
Current File : /home/opti/optisoftcom/.cpanm/work/1544535425.21555/Authen-SCRAM-0.011/devel/scram-examples.pl |
#!/usr/bin/env perl use v5.10; use strict; use warnings; use utf8; use open qw/:std :utf8/; use charnames ':full'; use Authen::SCRAM::Client; use Authen::SCRAM::Server; use Authen::SASL::SASLprep 1.100 qw/saslprep/; use JSON::MaybeXS; use MIME::Base64 qw/encode_base64/; use Tie::IxHash; use Path::Tiny; my $JSON = JSON::MaybeXS->new( ascii => 1, canonical => 1, pretty => 1 ); my @common = ( iters => 4096, salt => "saltSALTsalt", clientNonce => "clientNONCE", serverNonce => "serverNONCE", ); my @CRED_INPUTS = ( { label => "ASCII", user => "user", pass => "pencil", @common, }, { label => "ASCII user", user => "user", pass => "p\N{U+00E8}ncil", @common, }, { label => "ASCII pass", user => "ram\N{U+00F5}n", pass => "pencil", @common, }, { label => "SASLprep normal", user => "ram\N{U+00F5}n", pass => "p\N{U+00C5}assword", @common, }, { label => "SASLprep non-normal", user => "ramo\N{U+0301}n", pass => "p\N{U+212B}ssword", @common, }, { label => "no-SASLprep", user => "ramo\N{U+0301}n", pass => "p\N{U+212B}ssword", skipSASLprep => 1, @common, }, ); sub nice_string { join( "", map { $_ > 127 # if above ASCII ? sprintf( "\\u%04x", $_ ) # JSON-style escapes : chr($_) # else as themselves } unpack( "W*", $_[0] ) ); # unpack Unicode characters } for my $digest_name (qw/SHA-1 SHA-256/) { for my $c (@CRED_INPUTS) { my $cred = {%$c}; my $label = $cred->{label} = "$digest_name $cred->{label}"; my $niceuser = nice_string( $cred->{user} ); my $nicepass = nice_string( $cred->{pass} ); say "Test Case: $label"; say "User: '$niceuser'"; say "Pass: '$nicepass'"; my $client = Authen::SCRAM::Client->new( digest => $digest_name, username => $cred->{user}, password => $cred->{pass}, skip_saslprep => $cred->{skipSASLprep}, _nonce_generator => sub { $cred->{clientNonce} }, ); my ( $stored_key, $client_key, $server_key ) = $client->computed_keys( $cred->{salt}, $cred->{iters} ); my $prepped_user = saslprep( $cred->{user}, 1 ); my $prepped_pass = saslprep( $cred->{pass}, 1 ); if ( !$cred->{skipSASLprep} ) { say "Prepped User: '" . nice_string($prepped_user) . "'"; say "Prepped Pass '" . nice_string($prepped_pass) . "'"; } my $server = Authen::SCRAM::Server->new( digest => $digest_name, credential_cb => sub { my $user = shift; if ( $user eq $prepped_user ) { return ( $cred->{salt}, $stored_key, $server_key, $cred->{iters} ); } else { warn "BAD USERNAME MATCH FOR '$user'\n"; return; } }, _nonce_generator => sub { $cred->{serverNonce} }, ); my ( $c1, $c2, $s1, $s2 ); say "C1: " . nice_string( $c1 = $client->first_msg() ); say "S1: " . nice_string( $s1 = $server->first_msg($c1) ); say "C2: " . nice_string( $c2 = $client->final_msg($s1) ); say "S2: " . nice_string( $s2 = $server->final_msg($c2) ); $cred->{steps} = [ $c1, $s1, $c2, $s2, "" ]; say eval { $cred->{valid} = $client->validate($s2) ? \1 : \0; 1 } ? "Server: valid" : "Server: invalid"; say ""; $cred->{salt64} = encode_base64( delete $cred->{salt} ); $cred->{authID} = ""; $cred->{skipSASLprep} = $cred->{skipSASLprep} ? \1 : \0; $cred->{digest} = $digest_name; tie my %thash, "Tie::IxHash"; for my $k ( qw/label digest user pass authID skipSASLprep salt64 iters clientNonce serverNonce valid steps/ ) { $thash{$k} = $cred->{$k}; } my $fname = lc "$label.json"; $fname =~ tr[ ][-]; path($fname)->spew( $JSON->encode( \%thash ) ); } }