You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Rick Bradley <ri...@rickbradley.com> on 2002/10/03 21:08:04 UTC

Re: [mp2.0] wrong crypt behavior

On Fri, 6 Sep 2002 08:23:33 +0200 Toma'? Procha'zka <ka...@pef.mendelu.cz> wrote:
> For comparsion of password user entered and password stored in database is
> crypt function used.
> 
> Here is the code:
> my $real_pass = $d->[0][0]; # crypted password from database
> my $salt = substr $real_pass,0,2; # salt
> my $test_pass = crypt $sent_pw,$salt; # in $sent_pw is the password user entered
> if ($real_pass eq $test_pass) {
>  $r->subprocess_env(REMOTE_USER => $user);
>  return OK;
> } else {
>  $r->note_basic_auth_failure;
>  return AUTH_REQUIRED;
> }
> 
> Problem:  Sometimes, although user entered correct password, is authentication
> rejected. I tried logging values of $real_pass and $test_pass and they
> differed. When I add line
> 
> $r->log_reason("User $user tested (".$real_pass."/".$test_pass.")...","");
> 
> just before 'if' statement behavior is most of time correct.

I have also seen this problem.   I am using RT [0] and have intermittent
login problems where suddenly crypt() called from mod_perl will start
generating the wrong return values [ i.e., $pass ne crypt($user, $pass) ].
After some period of time the crypt() call will start generating the
correct values again.

Executing the exact same crypt() calls via a command-line 
perl -e 'print crypt([string], [string])' generates the expected
(correct) results.

If (in the code run by mod_perl) I replace:

if ($pass eq crypt($user, $pass)) {

with:

$crypt = `perl -e 'print crypt(\"$user\", \"$pass\")'`;
chomp($crypt);
if ($pass eq $crypt) {

Then everything works perfectly, though less quickly and blatantly
insecurely.  I have checked the failing $user, $pass and crypt() values
thoroughly for wierdness and compared them to their successful
counterparts.  I am 100% convinced that crypt() is returning the wrong
values.  Note that the wrong values are consistent (i.e., they are not
random, not changing, just not correct).

My original RT problem report (including voluminous configuration
information, but prior to the isolation of the crypt() issue) can be
found at:

http://lists.fsck.com/pipermail/rt-users/2002-September/010117.html


Question:  is crypt() thread-safe?  I haven't had a chance to look at
the source but I plan on doing so soon.

A tiny bit more info:

$ strace perl -e 'print crypt("foo", "bar")' 2>&1 | grep crypt
execve("/usr/bin/perl", ["perl", "-e", "print crypt(\"foo\", \"bar\")"], [/* 22 vars */]) = 0
open("/lib/libcrypt.so.1", O_RDONLY)    = 3

$ ls -al /lib/libcrypt.so.1 /lib/libcrypt-2.2.5.so 
lrwxrwxrwx    1 root     root           17 Sep 23 18:13 /lib/libcrypt.so.1 -> libcrypt-2.2.5.so
-rw-r--r--    1 root     root        19136 Sep 17 21:50 /lib/libcrypt-2.2.5.so


[0] http://www.bestpractical.com/rt/index.html

Rick
-- 
 http://www.rickbradley.com    MUPRN: 812    (???F/???F)
                       |  me a line. It's the
   random email haiku  |  only commercial unix
                       |  I've ever liked. Wow.

Re: [mp2.0] wrong crypt behavior

Posted by Rick Bradley <ri...@rickbradley.com>.
* Philippe M. Chiasson (gozer@cpan.org) [021003 23:42]:
> On my Linux box for example:
> 
> $> perl -V:version -V:d_crypt -V:d_crypt_r
> version='5.8.0';
> d_crypt='define';
> d_crypt_r='define';
> 
> So, you might need to look at if your platrofm supports crypt_r and make
> sure you are using a recent Perl that supports r_crypt. (Alternatively,
> you might want to try and apply that particular patch to see if your
> problem goes away before upgrading)
> 
> Hope this helps.

Very helpful.  I'll take a look at that tomorrow or Monday.

Thanks,
Rick
-- 
 http://www.rickbradley.com    MUPRN: 682    (73F/73F)
                       |  that I finally
   random email haiku  |  got a legitimite chance
                       |  to jumpstart my car.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: [mp2.0] wrong crypt behavior

Posted by Doug MacEachern <do...@covalent.net>.
On 22 Oct 2002, Philippe M. Chiasson wrote:

> On Tue, 2002-10-22 at 10:37, Doug MacEachern wrote:
> > does this patch (untested) cure the problem?
> 
> Works for me under all MPMs ;-)

excellent, many thanks for testing.  workaround committed to cvs.
 
> How about creating a new test script for all those workarounds/bugs ?

hmm, good idea, will this one work on all platforms?


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: [mp2.0] wrong crypt behavior

Posted by "Philippe M. Chiasson" <go...@cpan.org>.
On Tue, 2002-10-22 at 10:37, Doug MacEachern wrote:
> does this patch (untested) cure the problem?

Works for me under all MPMs ;-)

How about creating a new test script for all those workarounds/bugs ?

--- /dev/null	2002-08-31 07:31:37.000000000 +0800
+++ t/response/TestAPI/bugs.pm	2002-10-22 11:30:57.000000000 +0800
@@ -0,0 +1,19 @@
+package TestAPI::bugs;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+
+sub handler {
+    my $r = shift;
+
+    plan $r, tests => 1;
+    
+    #Perl crypt_r thread bug
+    ok crypt('foo','Dm') eq 'Dm8yjkphWW352';
+    
+    Apache::OK;
+}
+
+1;

> 
> Index: src/modules/perl/modperl_interp.c
> ===================================================================
> RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_interp.c,v
> retrieving revision 1.52
> diff -u -r1.52 modperl_interp.c
> --- src/modules/perl/modperl_interp.c	27 Aug 2002 04:24:08 -0000	1.52
> +++ src/modules/perl/modperl_interp.c	22 Oct 2002 02:48:38 -0000
> @@ -63,6 +63,14 @@
>  
>          interp->perl = perl_clone(perl, clone_flags);
>  
> +#if defined(USE_REENTRANT_API) && defined(HAS_CRYPT_R) && defined(__GLIBC__)
> +        {
> +            dTHXa(interp->perl);
> +            /* workaround 5.8.0 bug */
> +            PL_reentrant_buffer->_crypt_struct.current_saltbits = 0;
> +        }
> +#endif
> +
>          {
>              PTR_TBL_t *source = modperl_module_config_table_get(perl, FALSE);
>              if (source) {
> 
> 
> 


Re: [mp2.0] wrong crypt behavior

Posted by Doug MacEachern <do...@covalent.net>.
does this patch (untested) cure the problem?

Index: src/modules/perl/modperl_interp.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_interp.c,v
retrieving revision 1.52
diff -u -r1.52 modperl_interp.c
--- src/modules/perl/modperl_interp.c	27 Aug 2002 04:24:08 -0000	1.52
+++ src/modules/perl/modperl_interp.c	22 Oct 2002 02:48:38 -0000
@@ -63,6 +63,14 @@
 
         interp->perl = perl_clone(perl, clone_flags);
 
+#if defined(USE_REENTRANT_API) && defined(HAS_CRYPT_R) && defined(__GLIBC__)
+        {
+            dTHXa(interp->perl);
+            /* workaround 5.8.0 bug */
+            PL_reentrant_buffer->_crypt_struct.current_saltbits = 0;
+        }
+#endif
+
         {
             PTR_TBL_t *source = modperl_module_config_table_get(perl, FALSE);
             if (source) {



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: [mp2.0] wrong crypt behavior

Posted by Rick Bradley <ri...@rickbradley.com>.
* Philippe M. Chiasson (gozer@cpan.org) [021003 23:42]:
> crypt() is not required to be re-entrant, and is usually not re-entrant
> or thread-safe. But, some platforms provide a crypt_r() function, a
> re-entrant version of crypt. 

We looked into this some more and our Perl believes it is using crypt_r.
There is, evidently, a problem with Linux's glibc-2.2.5 implementation
of crypt():

http://marc.theaimsgroup.com/?l=perl5-porters&m=103012185631309&w=2

For the time being we can work-around until we move to a Perl (or a
glibc) which doesn't expose this issue.

Rick
-- 
 http://www.rickbradley.com    MUPRN: 374    (59F/57F)
                       |  drunken ass is just
   random email haiku  |  spilling out everything I
                       |  can think of. Enjoy.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: [mp2.0] wrong crypt behavior

Posted by "Philippe M. Chiasson" <go...@cpan.org>.
crypt() is not required to be re-entrant, and is usually not re-entrant
or thread-safe. But, some platforms provide a crypt_r() function, a
re-entrant version of crypt. 

Perl @15326 and onwards 5.8.* does the best it can and will attempt to
detect crypt_r and use if for crypt() operations, if it can't find it,
it'll default to regular crypt().

On my Linux box for example:

$> perl -V:version -V:d_crypt -V:d_crypt_r
version='5.8.0';
d_crypt='define';
d_crypt_r='define';

So, you might need to look at if your platrofm supports crypt_r and make
sure you are using a recent Perl that supports r_crypt. (Alternatively,
you might want to try and apply that particular patch to see if your
problem goes away before upgrading)

Hope this helps.

On Fri, 2002-10-04 at 03:08, Rick Bradley wrote:
> On Fri, 6 Sep 2002 08:23:33 +0200 Toma'? Procha'zka <ka...@pef.mendelu.cz> wrote:
> > For comparsion of password user entered and password stored in database is
> > crypt function used.
> > 
> > Here is the code:
> > my $real_pass = $d->[0][0]; # crypted password from database
> > my $salt = substr $real_pass,0,2; # salt
> > my $test_pass = crypt $sent_pw,$salt; # in $sent_pw is the password user entered
> > if ($real_pass eq $test_pass) {
> >  $r->subprocess_env(REMOTE_USER => $user);
> >  return OK;
> > } else {
> >  $r->note_basic_auth_failure;
> >  return AUTH_REQUIRED;
> > }
> > 
> > Problem:  Sometimes, although user entered correct password, is authentication
> > rejected. I tried logging values of $real_pass and $test_pass and they
> > differed. When I add line
> > 
> > $r->log_reason("User $user tested (".$real_pass."/".$test_pass.")...","");
> > 
> > just before 'if' statement behavior is most of time correct.
> 
> I have also seen this problem.   I am using RT [0] and have intermittent
> login problems where suddenly crypt() called from mod_perl will start
> generating the wrong return values [ i.e., $pass ne crypt($user, $pass) ].
> After some period of time the crypt() call will start generating the
> correct values again.
> 
> Executing the exact same crypt() calls via a command-line 
> perl -e 'print crypt([string], [string])' generates the expected
> (correct) results.
> 
> If (in the code run by mod_perl) I replace:
> 
> if ($pass eq crypt($user, $pass)) {
> 
> with:
> 
> $crypt = `perl -e 'print crypt(\"$user\", \"$pass\")'`;
> chomp($crypt);
> if ($pass eq $crypt) {
> 
> Then everything works perfectly, though less quickly and blatantly
> insecurely.  I have checked the failing $user, $pass and crypt() values
> thoroughly for wierdness and compared them to their successful
> counterparts.  I am 100% convinced that crypt() is returning the wrong
> values.  Note that the wrong values are consistent (i.e., they are not
> random, not changing, just not correct).
> 
> My original RT problem report (including voluminous configuration
> information, but prior to the isolation of the crypt() issue) can be
> found at:
> 
> http://lists.fsck.com/pipermail/rt-users/2002-September/010117.html
> 
> 
> Question:  is crypt() thread-safe?  I haven't had a chance to look at
> the source but I plan on doing so soon.
> 
> A tiny bit more info:
> 
> $ strace perl -e 'print crypt("foo", "bar")' 2>&1 | grep crypt
> execve("/usr/bin/perl", ["perl", "-e", "print crypt(\"foo\", \"bar\")"], [/* 22 vars */]) = 0
> open("/lib/libcrypt.so.1", O_RDONLY)    = 3
> 
> $ ls -al /lib/libcrypt.so.1 /lib/libcrypt-2.2.5.so 
> lrwxrwxrwx    1 root     root           17 Sep 23 18:13 /lib/libcrypt.so.1 -> libcrypt-2.2.5.so
> -rw-r--r--    1 root     root        19136 Sep 17 21:50 /lib/libcrypt-2.2.5.so
> 
> 
> [0] http://www.bestpractical.com/rt/index.html
> 
> Rick
> -- 
>  http://www.rickbradley.com    MUPRN: 812    (???F/???F)
>                        |  me a line. It's the
>    random email haiku  |  only commercial unix
>                        |  I've ever liked. Wow.
>