Scripted Authentication Using Netscape Directory Server

Suppose we’re using the Netscape Directory Server. It stores passwords in one of three ways: as cleartext, encrypted with the Unix crypt( ) function, or encrypted using S ecure Hash Algorithm (SHA). Here’s how the server represents an SHA-encrypted password as an attribute of a user object:

{SHA}W8r/fyL/UzygmbNAjq2HbA67qac=

The gobbledygook after {SHA} is another Base64-encoded value. It decodes to a 20-byte SHA hash. We can extract that value in hexadecimal form like this:

use MIME::Base64;
print unpack('H*', decode_base64('W8r/fyL/UzygmbNAjq2HbA67qac='));

The result is `5bcaff7f22ff533ca099b3408ead876c0ebba9a7', which is the hexadecimal representation of the SHA hash value of the password open sesame.

Like Unix’s crypt( ), SHA is a one-way hashing function. When you assign a password in Directory Server, it applies the one-way hash to the cleartext password to produce an encrypted password, which it stores in a user object in the directory. When a browser, mailreader, or newsreader tries to authenticate to a Directory Server-based application—such as Netscape’s web, mail or news server—the sequence of events is as follows:

The client sends a name and password to the provider of the service it’s requesting.

We’ll call this provider the application server, to distinguish it from the directory server. This client-to-application-server connection can be a cleartext channel or it can be SSL-encrypted. In either case the application server ultimately gets hold of a cleartext password.

The application server looks up the user in Directory Server and retrieves the encrypted password.

Again this channel may be cleartext or SSL-encrypted.

The application server compares the two sets of credentials.

It applies SHA to the cleartext password received from the user to produce an encrypted password. Then it compares that encrypted password with the one retrieved from Directory Server. If the two match, the application server accepts the credentials as authentic.

Although the hash algorithm itself is thought to be irreversible, which means that there is no way to recover a cleartext password from its hashed counterpart, all the usual caveats apply. We like to say that this kind of scheme authenticates a user, but really it just authenticates a set of credentials that may or may not have issued from that user. If I leave my browser logged in to a protected site and you walk up to my PC and start fetching pages, the cached credentials will still look just fine to the application server. Of course, the jig is up if I allow my cleartext password to travel over an unencrypted connection and you capture it with a sniffer. The jig may or may not be up if you gain access to my directory server and capture encrypted passwords. The passwords, even though encrypted, are vulnerable to brute-force dictionary attacks. For this reason the cryptographically ideal password is a long string of gobbledygook. Unfortunately that kind of password is worse than useless to the poor human who is supposed to use it, who can’t memorize a long string of gobbledygook and who will have to write it down on a scrap of paper and stick it to a keyboard or monitor. This dilemma is the Scylla and Charybdis of computer security, and there’s no simple way to navigate through it.

Bearing these caveats in mind, we can write a script that uses Directory Server in the same way that Netscape’s SuiteSpot servers do. We’ve already seen how to fetch attributes of a user object by using Group::LdapGroup. Here’s a fragment that fetches Aladdin’s SHA-encrypted password:

use Group::LdapGroup;

my $g = Group::LdapGroup->new("ldap.roninhouse.com",389,
        "o=RoninHouse","subscribers","uid=admin,o=RoninHouse",
        "admin_password");
print $g->getProperty("Aladdin","userpassword");

If we’ve received a password from a user who purports to be Aladdin, we SHA-encrypt the cleartext password and compare it to the encrypted one:

use MIME::Base64;
use SHA;

my $sha = new SHA;
$sha->add("open sesame");                    
my $digest = $sha->digest();                 # compute digest
my $password =                               # look up password in directory
  $g->getProperty("Aladdin","userpassword"); 
$password =~ s/(SHA{([^}]+)/;                # isolate password in $1
if ( $1 eq encode_base64($digest) )          # compare
        { print "Authenticated"; }
else
        { print "Not authenticated"; }
               
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.22.135