Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Authentication with /etc/shadow

by fluffyvoidwarrior (Monk)
on Feb 26, 2011 at 18:22 UTC ( #890329=perlquestion: print w/replies, xml ) Need Help??

fluffyvoidwarrior has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,
I need to authenticate user passwords on ubuntu server. I need to do this repeatedly and in bulk so I'm looking for a fast simple and lightweight method.

What am I doing wrong here?

# line taken from /etc/shadow
# fred:$6$ENtbbZ8/$dToEo6ohB/AjHGHhwsPXk0rsIXA/XmFaeUNJHnrBWoLqjX12rjUWLBTkkD9sH7pP4IrEsRMeB4/WMnQGPKJSJ/:14929:0:99999:7:::

my $hash = '$ENtbbZ8/$dToEo7hnr/AjHGHhwsPXk0rsIXA/XmFaeUNJHnrBWoLqjX12rjUWLBTkkD9sH7pP4IrEsRMeB4/WMnQGPKJSJ/';
my $salt = '$6';
my $password = "this_is_my_password";

if (crypt($password, $salt) ne $hash) {
  print "Password doesn't match";
  print "Password does match"

ps. names and hashes have been changed to protect the innocent. - ie these aren't real values.

Thanks .... again.

Replies are listed 'Best First'.
Re: Authentication with /etc/shadow
by ELISHEVA (Prior) on Feb 26, 2011 at 20:03 UTC

    Rather than try to work directly with /etc/shadow have you considered using Perl to interface with PAM (pluggable authentication module for Linux)? There are several modules available on CPAN: PAM.

    By going to etc/shadow directly you are bypassing whatever additional checks and validations or security alternatives have been configured for your system's users via PAM.

      Yes, I considered using PAM and the associated perl modules

      I discarded this approach because it seemed to be likely to introduce quite a bit of system overhead and I'm really going to be hammering it - potentially a max of 50 checks per second.

      I thought a quick crypt comparison on etc/shadow would be faster and less intensive - ie load the whole file into an array and parse it with regex, etc.

      I don't want to labour my cpu with password checks

        I can't help feeling there is something fundamentally inconsistent in your reply here and your response to fullermd. I'll grant that you know your client and your situation and you may be limited in your ability to explain your true requirements but... just food for thought.

        You write, in reply to fullermd

        The main security risk I can see is the possibility of an attacker copying my program (stealing a hard drive or system unit wouldn't work) and running it on his computer to gain access via a hole in the wall...I only need to delay an attacker a few hours and his attack becomes pointless. Though he can steal the program and run on it on his computer I am hoping he is unlikely to clone my users. I want to authenticate my system users with every pass of my program loop and shred my perlapps if any of various conditions

        If security is so very important to your client, about the last thing you should be considering is an end-run around PAM. The more places security is defined, the more places changes to security protocols need to be updated, and the more long term problems. Also the more places you need to secure and protect from access. By adding a second authentication mechanism outside of PAM you are in fact increasing the number of potential attack vectors.

        Second, modern versions of PAM support some pretty sophisticated user identification mechanisms, including bio-identification. Presumably, if those scripts are run on a personal computer, they have to log in at some point into the sensitive computer. I'm going to assume you are sophisticated enough to never ever put login information in the clear in your scripts, especially in a high security situation.

        Why aren't you making your scripts owned by a user who can only be activated with a bio marker? Then it wouldn't matter what computer your would-be attacker ran the program on: when he tried to access the sensitive computer and reached the bio-security check, he'd be stopped dead in his tracks.

        Third, if this is really so very important to your client and you really have no option but to run security checks before each and every operation, your client should be willing to provide a box with sufficient memory and CPU to handle the hit rate and security checks.

        Forth, if stealing a disk won't work, how is it that these scripts are being stolen or copied in the first place? How is it that merely running the scripts on a personal computer would give someone access? That doesn't sound right at all. Have you considered front-ending the computer with these valuable scripts with a gateway computer that validates the users? Putting these scripts on a secure computer accessible only via the IP of that gateway computer or by an on-site login with bio-id? Limiting the actions those users can take?

        Fifth, if your scripts can be stolen or copied, why wouldn't your user base be stolen or cloned? Seems to me that would be a much more direct way of cracking your system. Why wouldn't a serious attacker read your source code? I certainly wouldn't write off a script as not worth reading even if it contained only one line in it. Would you? I hope not. I'm not following your logic when it comes to likely cracker behavior.

        Sixth, if security is essential to your client, should you even be using scripts for such sensitive operations? Might it not be wiser for both performance and security reasons to go with a compiled executable? With any scripting solution there is always a risk that an enterprising hacker can intentionally create and take advantage of time gaps between the launching of the Perl interpreter and the loading of your script to change the effective user id or wreck other havoc. If you must use scripts you might want to take a good hard look at the implementation and security checks done by Apache's mod_suexec.

        Seventh, I question your logic that a pure Perl script hacking /etc/shadow would in fact be faster. If PAM is doing nothing more than a password check, my first guess is that it would be faster because you are using pre-parsed code compiled into machine code ops. With a script you have to parse and compile it with each run. Even if you are pre-loading modules and using signals or function calls for each user check, you'd still be running Perl OP codes which have to be translated into machine ops rather than machine ops. If PAM is doing more than a simple password check, then you aren't really doing a complete authentication if you by-pass PAM and as soon as your would be hacker figures that out, they'll find a backdoor through the things you aren't checking.

        I don't know your situation, but based on what you've shared so far, it seems to me that you are trying to solve a problem with scripting that needs to be solved in a much more systemic way. I think you need to have a very serious talk with your client.

        Please don't.

        In my programming life, I've seen at least 2 orders of magnitude more problems caused by people manually mucking about with things that have nice defined API's for fanciful reasons, than problems caused by something being too slow for doing so.

        If it's a problem, find out that it's a problem first, then fix it. And in this case, you'll eat the crypto overhead either way, so what do you think you'll save?

Re: Authentication with /etc/shadow
by JavaFan (Canon) on Feb 26, 2011 at 18:44 UTC
    You said, you have changed the hash. Perhaps the hash started with $1$? Because the GNU libraries have two ways of encrypting passwords: traditional DES using a 2 character seed, or an MD5 based encryption that uses a key of the form '$1$...$', where '...' is up to 8 characters.

    See also your systems crypt manual page.

      Yes, thanks.

      I chopped the first 2 chars off to use as the salt but, as you said, the hash actually started $6$ with a $ delimiter at the 8th char.

      so this must be the MD5 format

      The start of the hash is "$6$ENtbbZ8/$" so the $salt would be "ENtbbZ8/" ? ...
      and then my little code snippet might work?

      Will check out the crypt manpage Thank you.
        so this must be the MD5 format

        I believe that would be SHA512, the passwords start with $6$ -- Crypt::Password can handle it, I think.

Re: Authentication with /etc/shadow
by justanyone (Acolyte) on Feb 28, 2011 at 21:54 UTC
    LDAP is your friend. Already written. Servers exist. Databases exist. Modification tools exist. Life is good if you conform to the standard toolset for this task.
    Kevin J. Rice
    Homepage(with email on it):

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://890329]
Approved by Corion
Front-paged by chrestomanci
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2019-06-16 11:24 GMT
Find Nodes?
    Voting Booth?
    Is there a future for codeless software?

    Results (76 votes). Check out past polls.