Your Daily Source for Apache News and Information  
Breaking News Preferences Contribute Triggers Link Us Search About
Apache Today [Your Apache News Source] To internet.com

Free trial with SiteScope. $10 Amazon Certificate.

Apache HTTPD Links
The Apache FAQ
The Java Apache Project
The Apache Software Foundation
Apache-Perl Integration Project
Apache Module Registry
Apache Project
Apache XML Project
PHP Server Side Scripting
The Jakarta Project
Apache-Related Projects
ApacheCon
The Linux Channel at internet.com
Linux Apps
Enterprise Linux Today
BSD Today
BSD Central
Linux Programming
PHPBuilder
Linuxnewbie.org
Apache Today
Linux Today
Just Linux
Linux Start
Linux Central
Linux Planet
All Linux Devices
SITE DESCRIPTIONS
Apache Guide: Apache Authentication, Part 4
Aug 14, 2000, 03 :40 UTC (18 Talkback[s]) (20391 reads) (Other stories by Rich Bowen)

By

In the last three articles, I've talked about authentication on Apache: asking the user for a username and password to get at your stuff. This week I'll cover some techniques for automating the maintenance of your password lists with Perl. Doing it all by hand can be a real drag.

Warning: This article assumes that you already have a grasp on the basics of Perl.

Perl

In case you don't know what Perl is, here's the simple explanation: it's a programming language. It's a very popular programming language, favored by folks for doing tasks that require text manipulation, sockets communication, orchestrating various applications in some way, and a plethora of other tasks. It is reputed to be very popular as a CGI programming language also, but that's only a smidgen of the whole story, and tends to sell Perl short by people who think, "Oh, that's just a CGI language."

Encrypting a Password

One of the things that is going to come in very handy in managing user and password lists is the ability to encrypt a password. The good news is that Perl has a built-in function to do just this. It's called crypt. In order to use it, you need to understand a few things.

First, as mentioned in an earlier article, Apache stores passwords in what's know as "Unix crypt" format. Perl's crypt function produces this same format. To encrypt a string, you need something called the "salt." The salt is a two (or more) character string that is used to get the encryption started. The salt is usually generated randomly, and so the string will end up being encrypted differently depending on the salt that was picked.

To call the crypt function in Perl, you'd do the following:

        $encrypted = crypt ($password, $salt);

In the above code example, $password is assumed to have been supplied by the user in some fashion, and $salt is assumed to have been generated in some fashion. More on this later.

Crypt is a one-way encryption algorithm. What that means is that once you have encrypted a string, there's no way to decrypt it--to get it back to it's original format. This means that the only way to tell if a particular password is the same as the original is to encrypt that password, and see if you get the same thing. Of course, you have to encrypt it with the same string. Conveniently, crypt leaves the salt in the first two characters of the encrypted string, so you just have to do something like this:

        $guess_encrypted = crypt ($guess, $encrypted);
        if ($guess_encrypted eq $encrypted)     {
                print "You guessed right.\n";
        }
        else {
                print "Wrong password, try again.\n";
        }

When you specify a particular string as the salt, Perl knows to just use the first two characters of that string.

By the way, to generate a salt yourself, you can use something like this:

        @a=(0..9,'a'..'z');
        $pass = join '', map { $a[int rand @a] } (0..1);

That just generates a 2-character string composed of random numbers and letters. And, as always in Perl, there's more than one way to do it.

Adding a Password to a Password File

We've talked about three ways to store your usernames and passwords. First, three weeks ago, we talked about using plain text files. Two weeks ago, we talked about using DBM files. And last week, we talked about using a MySQL database.

There are several ways to handle putting passwords into each type of storage mechanism. In each case, you can do things "by hand", or you can use one of the existing CPAN modules to do a lot of the work for you.

The CPAN module to look for is HTTPD::UserManage. It was written by Lincoln Stein and Doug MacEachern, and allows you to manage multiple types of authentication mechanisms, on multiple server-types (Apache, Netscape, etc) via one interface.

You can get HTTPD::UserManage from your favorite CPAN mirror. It also comes with a CGI application that, when correctly installed, lets you manage your authentication files from the web. Pretty cool stuff.

There are also a couple of other modules - Apache::Htpasswd and Apache::Htgroup, that give a simple, Apache-only interface for managing your authentication files.

Adding a password to a Text Password File

If you want to add a password to a text htpasswd-type password file, without the benefit of modules, here's how you'd do it:

        open PASSWD, '>>/path/to/.htpasswd';
        print PASSWD "$username:$encrypted\n";
        close PASSWD;

Well, you say to yourself, that's pretty darned simple. Why would I want to use a module to do that? Three reasons. One, if you're going to be doing this hundreds or thousands of times, you'll find it much easier to be able to call one function, passing in the username and desired password, than encrypting the password yourself and running the above code. Secondly, the modules provide you with a lot of other functionality, such as verifying a password, and deleting a user. Thirdly, if you're using HTTPD::UserManage, and you decide a year from now to change to using mod_auth_mysql instead of htpasswd files, you don't have to change any code. That third one is a big win, because some day you will want to change your authentication method, and you don't want to be stuck with changing code a dozen places, and potentially missing a few. Trust me. I missed a few.

Passwords in DBM Files

DBM files are the fun ones, because they let me use a pretty cool feature of Perl. Perl has a key work called tie. As the name suggests, it lets you tie one thing to another. In this case, it lets you tie a variable (in particular, a hash) to a DBM file. So, when you modify the hash, the DBM file automatically gets modified for you. Very cool stuff.

This looks like the following:

        use DB_File;
        my %database;
        tie %database, 'DB_File', "passwords.dat"
            or die "Can't initialize database: $!\n";
    $crypt = crypt($password, $salt);
        $database{$username} = $crypt;
        untie %database;

And, voila, you have an entry in the password file associating user $username with their password.

Note that you should, of course, not put your password file inside your web root, where someone can download it and crack it at their leisure. The above code is just an example.

Passwords in MySQL Databases

This is the most obvious one. In fact, most often when you use mod_auth_mysql, it's beacase you already have user information in a database, and want to use if for authentication.

Information can be updated in the database with regular SQL statements, and DBI:

        use DBI;
        my $dbh = DBI->connect('DBI:mysql:database', 'username',
     'password'); # 'password' is the database password.
        my $sth = $dbh->prepare("update passwords
                set passwd = '$crypt' where username = '$username'");
        $sth->execute;
        $sth->finish;
        $dbh->disconnect;

Summary

This was a lightning-fast overview of how one might use Perl to manage your password lists, in any of the three storage mechanisms that we've talked about over the last three weeks.

Future columns

Please let me know if there are other topics that you'd like for me to talk about in future columns. You can send your suggestions to me at And please let me know what you think of my columns, at that same address. Many thanks for reading down this far!

--Rich

  Current Newswire:
perl.com: mod_perl in 30 minutes

Sun to allow open source Java implementations

SECURITY: Vulnerability in Apache for Win32 batch file processing

WebReference.com: mod_perl Developer's Cookbook

mod_l33t added to Apache Module Registry

Linux Easy Installer - Security Fixes

Daemon News: Jakarta-Tomcat on FreeBSD 4.4

Moto, a compilable server-side scripting language

SECURITY: Flaws Found in PHP Leave Web Servers Open to Attack

Everything Solaris: Apache: Handling Traffic

 Talkback(s) Name  Date
I've browsed through the last two articles in this series. There's plent ...   Using authentication   
  Aug 16, 2000, 15:04:31
> I've browsed through the last two articles in this series. There's ple ...   Re: Using authentication   
  Aug 22, 2000, 12:22:08
I'm not sure if that's a 100% correct method but you can check the envir ...   Re: Using authentication   
  Nov 7, 2000, 18:08:53
Higreat article.I was interested in possibly applying the last method (passwords ...   Apache Authentication part 4   
  Aug 17, 2000, 19:43:42
I'm trying to find out how to cancel the authentication. In other word, I&#3 ...   Cancelling Authentication   
  Nov 28, 2000, 05:39:26
p.s. wouldn't $crypt and $username be interpretted as literal strings with ...   Re: Apache Authentication part 4   
  Aug 21, 2000, 13:32:32
The crypt() method is pretty standard. It's not specific to Perl. So any lan ...   Re: Apache Authentication part 4   
  Aug 22, 2000, 12:25:59
Hello!I also use Perl for my CGI scripts. For checking userID I use $ENV{"REMOTE ...   User authentication   
  Dec 17, 2000, 13:26:51
Is it possible to dynamically create an htaccess file that can redirectbased on ...   Are Dynamic HTAccess Files Possible???   
  Mar 10, 2001, 08:56:34
Is there any module available to timeout a login - so that Apache will automatic ...   Timeouts with authentication   
  Mar 12, 2001, 21:16:57
Where can i found mod_auth_pgsql?? if it is posible rpm formatI need it!! ...   Where can i found?   
  Apr 26, 2001, 07:20:50
I think you should mention that system using MD5 passwords, the crypt will not w ...   MD5   
  Aug 24, 2000, 07:07:59
I installed Apache 1.3.12 w/ mod_ssl on my FreeBSD 4.1R.When I want to access so ...   Authorization failed??   
  Aug 29, 2000, 13:21:27
> I installed Apache 1.3.12 w/ mod_ssl on my FreeBSD 4.1R.When I want to access ...   Re: Authorization failed??   
  May 3, 2001, 16:50:09
A bit desperate here. This is probably a stupid question.I have user logging in ...   Passing credentials to another Apache server   
  Oct 5, 2000, 02:35:00
> A bit desperate here. This is probably a stupid question.I have user logging ...   Re: Passing credentials to another Apache server   
  Oct 15, 2000, 19:36:44
If I was going to pas credentials on, I would have SSL Certs (try Onsite from Ve ...   Re: Passing credentials to another Apache server   
  Feb 7, 2001, 21:24:44
Guess you have a couple of options, you could frame the request and have the ext ...   Re: Re: Passing credentials to another Apache server   
  Jan 10, 2001, 10:53:13
Enter your comments below.
Your Name: Your Email Address:


Subject: CC: [will also send this talkback to an E-Mail address]
Comments:

See our talkback-policy for or guidelines on talkback content.

About Triggers Media Kit Security Triggers Login


All times are recorded in UTC.
Linux is a trademark of Linus Torvalds.
Powered by Linux 2.4, Apache 1.3, and PHP 4
Copyright 2002 INT Media Group, Incorporated All Rights Reserved.
Legal Notices,  Licensing, Reprints, & Permissions,  Privacy Policy.
http://www.internet.com/