Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Hello Monks

I apparently signed up for blogs.perl.org some time ago, and I have no idea what password I used. With the leak of my credentials (unfortunately my username is on the list) I would like to verify what password I used.

Since the crypt function is a one way hash function, I was going to "crypt" my standard passwords, but I'm having trouble identifying where the SALT value comes from.

Full disclosure, I tried to ask on irc.freenode.net #perl and was told to RTFS, (even though I had been), and when I tried to ask questions about the source (because frankly the begin block below makes no sense to me... it looks like it's modifying the symbol table directly, but to what end?) I was told again to RTFS.

I'm hoping against all hope that you are nicer than the people on irc, because frankly I'm a bit hot under the collar right now (and I now understand all the gripes about how shitty people in the Perl community are... having never experienced it for myself). (I get that people on irc and here are volunteering their time, but that's no reason to be rude about it. Besides this is a serious breach of security and I'd just like a _little_ help to gain a piece of mind. I don't _usually_ reuse passwords, but again, I have no idea what password I used on blogs.perl.org).

Anyway, I digress, from the Movable Type docs:

MT::Author =head2 $author->set_password($pass) One-way encrypts I<$pass> with a randomly-generated salt, using the Un +ix I<crypt> function, and sets the I<password> data field in the I<MT::Au +thor> object I<$author>. Because the password is one-way encrypted, there is B<no way> of recov +ering the initial password. =head2 $author->is_valid_password($check_pass) Tests whether I<$check_pass> is a valid password for the I<MT::Author> + object I<$author> (ie, whether it matches the password originally set using I<set_password>). This check is done by one-way encrypting I<$check_pa +ss>, using the same salt used to encrypt the original password, then compar +ing the two encrypted strings for equality.

The documentation for is_valid_password in MT::Auth is very similar:

MT::Auth =head2 MT::Auth->is_valid_password($author, $password, $crypted, \$err +or_ref) A routine that determines whether the given password is valid for the author object supplied. If the password is already processed by the 'crypt' function, the third parameter here will be positive. The \$err +or_ref is a reference to a scalar variable for storing any error message to be returned to the application. The routine itself should return 1 for a valid password, 0 or undef for an invalid one.

This says to me that the function is_valid_password somehow "magically" knows the SALT, but I don't understand HOW is_valid_password is getting that salt value, it's not being passed in as a parameter...

It looks to me that the salt value is a randomly generated two character salt:

sub set_password { my $auth = shift; my($pass) = @_; my @alpha = ('a'..'z', 'A'..'Z', 0..9); my $salt = join '', map $alpha[rand @alpha], 1..2; # FIXME: use something besides 'crypt' $auth->column('password', crypt $pass, $salt); }

It looks like MT::Author::is_valid_password is just a proxy for MT::Auth::is_valid_password, as it just calls MT::Auth::is_valid_password with the parameters passed to it:

sub is_valid_password { my $author = shift; my($pass, $crypted, $error_ref) = @_; $pass ||= ''; require MT::Auth; return MT::Auth->is_valid_password($author, $pass, $crypted, $erro +r_ref); }

Here's where I really don't understand, MT::Auth::is_valid_password doesn't seem to be defined, but in MT::Auth it looks like we're modifying the symbol table directly:

BEGIN { my @methods = qw( errstr sanity_check is_valid_password can_recover_password is_profile_needed password_exists validate_credentials invalidate_credentials delegate_auth can_logout synchronize synchronize_author synchronize_group new_user new_login login_form fetch_credentials ); no strict 'refs'; foreach my $meth (@methods) { *{"MT::Auth::$meth"} = sub { shift; _handle($meth, @_) }; } }

(It was when I asked for help understanding the above block of code that I was told I should RTFS for the second time).

My guess is that this code is shifting of the obj reference (since the object is passed as the first parameter when calling an object method), then passing the rest of the parameters to _handle. The following block is a block inside of main, so $auth_module is "cached" so _driver doesn't have to be called on every invocation. It seems like _driver is just instantiating an object of MT::Auth::$SOMETHING (my best guess is BasicAuth in this case), but then _handle is calling $method on some $object. (but if $method is is_valid_password then it can't do that because MT::Auth::BasicAuth doesn't define an "is_valid_password")

This is wrinkling my brain. What is going on here?

{ my $auth_module; sub _driver { my @auth_modes = split(/\s+/, MT->config->AuthenticationModule); foreach my $auth_mode (@auth_modes) { my $auth_module_name = 'MT::Auth::' . $auth_mode; eval 'require ' . $auth_module_name; if (my $err = $@) { die (MT->translate("Bad AuthenticationModule config '[_1]' +: [_2]", $auth_mode, $err)); } my $auth_module = $auth_module_name->new; die $auth_module_name->errstr if (!$auth_module || (ref(\$auth_module) eq 'SCALAR')); return $auth_module; } die(MT->translate("Bad AuthenticationModule config")); } sub _handle { my $method = shift; my $mod = $auth_module ||= _driver(); return undef unless $mod->can($method); $mod->$method(@_); } sub release { undef $auth_module; } }

I am curious as to what is going on here, I'm always looking for strategies to improve my code, but that is extremely low priority in comparison to verifying what password was leaked.

I asked the same question on reddit but /r/perl is not nearly as active as perlmonks.

Thanks for any assistance.

EDIT:

This appears to be the is_valid_password in MT::Auth::MT, my guess that we'd be using MT::Auth::BasicAuth is incorrect (I think)

sub is_valid_password { my $auth = shift; my($author, $pass, $crypted, $error_ref) = @_; $pass ||= ''; my $real_pass = $author->column('password'); if ((!$real_pass) || ($real_pass eq '(none)')) { return 0; } return $crypted ? $real_pass eq $pass : crypt($pass, $real_pass) eq $real_pass; }

Many thanks to Corion and Anonymous Monk for their assistance with this one


In reply to [SOLVED][blogs.perl.org credential release] How can I check the password that I used on blogs.perl.org by three18ti

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-26 00:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found