Perl CGI Script to manage multiple usernames/passwords

NOTE: Not Freeware.

.htaccess manager : New Version 3.3

This is a perl CGI script used to manage multiple usernames/passwords for .htaccess/.htpasswd directory protection. This works on most web sites and can be used to handle many password protected folders. In addition to storing the username and encrypted password, you may add additional info for your members such as name, e-mail and comments to help you manage who has access to your “members only” web site. New features include setting an expiration date for a user, keyword search of your members’ list and batch removal of users.

FEATURES

Adding a New user

The “Add User” function is the first that appears after logging into the script. You just need to supply a username and password then click “Add User”. All the other fields are optional. Even the password field can be left blank and the program will pick one at random. You can also supply the member’s name, e-mail address and a short comments field. If you check the box “Check to email new entry to user”, this will tell the program to send out an email with pre-configured text welcoming the user as a new member to your password protected area. If you do check this box, then you can also provide additional text in the large “Extra E-mail Text” box which will be passed along in the email sent out.

You can now add an expiration date for the user, enter it in the format YYYYMMDD (20030631 for example). The script does not automatically delete users but you have the option of sorting your user list by expiration date. This field is optional and you do not have to enter an expiration date.

View, Modify and Delete Users

The “List User” screen does three things, it provides a list of all your members, allows you to delete a member and modify any information for a particular member. The user list shows “Username – Member Name – Email address – comments”. You can easily control the size of this box by changing the scrollsize option in the program settings. To delete a user all you have to do is highlight then click the delete button. To Modify a user, you also highlight the record then you can modify the password, name, email and comments field. You can even check the box to resend their confirmation email. If one of your members forgets their password, you just come to this screen, highlight them, enter a new password, check the “e-mail” box and click “Modify User”.

Sort By Expiration : Will sort all of your members by expiration date in ascending order.
Sort by username : Sorts the list by username (the default view)
Keyword Search : Will search the username, name, email, comments and expiration field for whatever you type in

Change Directory

“Change Protected Directory” screen allows you to manage password protection on another folder. This also makes it easier than going back to the login screen. This screen displays the path you have setup where your password protected directories will be located. You just type in the new folder name and click “Change Directory”. This way you can use the script to manage as many password protected folders as you like. If you are protecting a folder within another folder then you type in for example : member_area/secure1 and then the script will manage the “secure1″ folder located in the “member_area” folder. You will also find two additional buttons on this screen. One is to view the .htaccess file and the other for the .htpasswd file. This is a good thing to do every now and then so you can make backups of your member database.

Generate .htaccess File

When you first setup password protection on a folder, you need to create a .htaccess file inside it. You can either do this manually or have the script create this file for you. You do not need to do this every time you add a user. Once a .htaccess file has been created in a folder, you don’t need to run this function again. The Directory field will display the folder name you are about to generate a .htaccess file for. The Realm is for the message that will be displayed in the pop-up box that appears when a user tries to login to your secure area. If you want the script to create the file, then check the “Create .htaccess file on Server”. As for the format you want, the majority of unix servers use “.htaccess file for apache” Some web hosting companies use Cobalt RAQ or Zeus.

Password Retrieval (Version 3.2+)

You can now have your members generate new passwords for themselves if they forget their login information. To activate this feature in the script, send your users to :

http://www.yourdomain.com/admin.cgi?action=F&targetdir=dirname

Where “dirname” is the name of the directory you are protecting (same directory you type in when accessing admin.cgi)
If a member forgets their username, they just type in their email address and it will be sent to them. If they forget their password, they just type in their e-mail and username then a new password will be generated.

Version 3.3 just added the option for users to select their own new password if they supply their username and their old password.

Extract E-mails

Extract E-mails allows you to export a list of all your members’ email addresses. The list will be formatted one email address per line. Some email programs require that each address have a comma after it which you can select when exporting. The addresses will appear on the next page which you can then copy/paste into Eudora/Outlook etc.

Mass E-mails (Version 3.2+)

Allows you to send a broadcast email message to all members. E-mails can be configured to send specific information about each user using the %tag%.
Example : Hello %name%,
Your userid is : %username%
Your email is : %email%
Your account expires on : %expiration%
Comments about your account : %comments%

Manual Import

If you have a large list of usernames that you want to add as members in just one click then the Manual Import feature will handle this. All you do is copy/paste or type the list into the large text box. Here is a sample of what the list would look like :
username,password
joe,joe123
jack,jack887
jane,janepass

You can also import the additional fields :
username, password, name, email, comments, expiration
joe,joe123,Joe Smith,joe@smith.com,friend
jack,jack887,Jack Smith,jack@smith.com,

Also, you can even leave the password field blank to have the script automatically generate it for you :
joe,,Joe Smith,joe@smith.com
jack,,Jack Smith,jack@smith.com
(note the two commas after eachother)

You can also automatically send an email to each member that you import by checking the “Send E-mail” box. Even the comments field can be sent if you wish.
Whenever you run the import, the script will always check to make sure that the username doesn’t already exits. If any username in your list exists, no records will be imported.

Import From File

The import from file feature is if you have a list of members too large to fit in the manual import box or maybe you have another program that exports the list of usernames/passwords to a file that need to be imported later. By default, the name of the file that the program looks for is called htimport.txt and will be located in the directory you are protecting. The format for records to be imported is the same as the manual import :
username,password
or
username,password,name,email,comments, expiration
or
username,,name,email,comments

Whenever you run the import, the script will always check to make sure that the username doesn’t already exits. If any username in your list exists, no records will be imported.

Change Program Settings

This screen allows you to update configurations in the program without having to manually edit the admin.cgi script. The settings you can change are :
Base directory : The physical server path to where your protected folder or folders are located. (Not to be confused with the URL or domain name to your web site). example : /www/yourdomain/htdocs/

Password : The master password to access the admin.cgi script with.
Sendmail : The path to sendmail for your server.
Scroll Size : The number of members that will be displayed in the “List Users” screen before it scrolls.
Email From : Your e-mail address goes here. This is also the address used when sending email confirmations to your new members, they will see this in the From field. You can also add your name in parenthesis : joe@smith.com (Joe Smith)
Email Subject : The subject of the emails which are sent out to new members.
Top of Email : The text that will appear in the email sent to users. After this text will come the username and password.
Bottom of Email : The text that will appear after the username/password and the end of the email.
The data for all these variables is stored in a file called adminvars.cgi
You do not need to create this file on the server. If the file is not there it will be created with default settings. If for some reason your script does not have permission to create the file, you may need to upload a blank one and chmod it to 777. The default admin password is test.

FAQ

  • Does my server support .htaccess ?
    In the majority of cases, if it’s unix and runs the apache server then yes. The best way to find out is by uploading a .htaccess file to a subdirectory on your server then access it with your browser and see if it asks you for a login.

    • Here’s one you can use on your site : .htaccess upload this file to a directory on your server (in ASCII mode), example : yourdomain.com/members/ then rename it to .htaccess (yes, that’s a period infront of “htaccess”)
    • Then using your browser, go to http://www.yourdomain.com/members/ If you’re prompted to enter a username and password, then it will work!
  • After a member enters their username/password to the protected directory, do they need to re-enter it each time they access a new file ?
    No, the way .htaccess works, is it protects all files in the directory it is in. So once a user is authenticated, they have access to everything in that folder. But if a user bookmarks a page in the secure area, they will be required to re-enter the user/pass if they shut down their web browser and restart.
  • Can I protect multiple directories with the same list of users ?
    Yes, in this case, you would have the admin.cgi script only manage one of the directories for you, then all you would need to do is copy the same .htaccess file over to the new directory you want to protect. If you look in the .htaccess file, it says right there the full path to the .htpasswd file it will look for to authenticate users AuthUserFile /home/secure/.htpasswd.
  • Can I protect multiple directories with a different list of users ?
    Yes, in this case, you just run the admin.cgi script and tell it to refresh to a new directory to access that list of users. By doing this, each directory will have its own .htpasswd and .htaccess file.
  • Will this work with Frontpage Extensions ?
    Yes, 90% of the time it will. Just as long as the directory you are protecting is setup as a regular directory in frontpage and not a “subweb”. The idea is to tell Frontpage not to overwrite the .htaccess file that admin.cgi creates
  • Can the script automatically send passwords to users who forget their login ?
    Yes, this feature is available as of version 3.2. Just provide a link for your members to admin.cgi?action=F&targetdir=dirname. They just have to supply their e-mail address and username then the script will generate a new password and e-mail it to them.
  • How do I configure the e-mail that is sent to members ?
    When you add a new user, you have the option of sending them an e-mail with their new username/password (saves you the time of having to do it manually each time). You can configure the subject of the emails, the sender’s name and e-mail address (you) and the text in the body of the email. These settings can be changed by logging into admin.cgi and scrolling down to the section labeled “Change Program Settings”. You can read about this in the Features page.
  • How do I add a long list of users at once (instead of adding them one at a time) ?
    This is what the Manual Import feature does. After running the script, scroll down to “Manual Import” and you’ll see a large TEXT box, this is where you can copy/paste your list of users. See the Features page.
  • Will this script work on NT server ?
    No.
  • I don’t know anything about CGI, chmod etc. can I still use it ?
    Not a problem, we’ll install the script for you. When you place your order, be sure to provide your URL (http://….) ftp username and password. Almost all installs are completed the same day you place your order.
  • What if the program does not run on my server, is there a refund ?
    We will not charge your credit card until the program works successfully on your web hosting account/server. Credit cards are usually processed a few days after you submit your order.
  • Automatic Post-commit Checkout

    Subversion can be a very useful tool for developing Web sites or Web-based applications. You may wonder, though, how that would work. After you commit your changes to your repository, how do you have them reflected on your site? The easiest method is to have your site’s directory on the server be a working copy checked out from your Subversion repository. If you elect to do this be certain to modify your site’s .htaccess to prevent users from browsing Subversion’s control files. Something simple in the root of your site such as the following will suffice.

    RedirectMatch 403 /\.svn.*$

    Additionally you can configure your site to automatically check out the current sources from your repository by using Subversion’s “hook scripts“. In short, the script called hooks/post-commit will be executed by the web server each time new sources are checked into your repository. Be advised that when the web server executes this script it is running in the security context of the dhapache user — this user does not and should not (for security reasons) have the necessary permissions to modify the files in your web site’s directory. As such we need to arrange for the post-commit script to run the update in the security context of a user with the privileges necessary to update your site.

    Users familiar with UNIX systems will recognize that this is a task for a setuid binary. Unfortunately the DreamHost /home/ directories are NFS filesystems which are, for security reasons, mounted with setuid disabled. Fortunately the workaround is trivial — simply set up your update script as a CGI script and have the Subversion post-commit hook invoke this script. Instructions follow.

    1. Create a private directory on your website to host your updater script such as /home/username/mysite.com/cgi-bin/pri

    1b. And set its permissions so that only the user has write access to it.

    chmod 755 pri

    2. Secure the private directory by creating a .htaccess file with contents similar to the following.

    AuthName "Dialog prompt"
    AuthType Basic
    AuthUserFile /home/username/mysite.com/cgi-bin/pri/.htpasswd
    Require valid-user

    3. Using the htpasswd utility create the .htpasswd file by running the following command in your /home/username/mysite.com/cgi-bin/pri directory. For security reasons make up a new username and password and do not re-use the username and password of a user you have created on your server or a user you have given access to your subversion repository.

    htpasswd -bc .htpasswd someuser somepasswd

    4. Now that you have created and secured a directory for this special CGI script to live in, create a script in that directory called do_update.cgi with the following contents.

    #!/bin/sh
    set -f
    echo "Content-type: text/plain; charset=iso-8859-1"
    echo
    /usr/bin/svn update /home/username/mysite.com

    4b. Don’t forget to give execution privilege to your file. Only the user can have write access to it.

    chmod 755 do_update.cgi

    5. Finally, modify your /home/username/svn/projectname/hooks/post-commit to invoke your CGI script so your site will update after each commit.

    #!/bin/bash
    wget --http-user=someuser --http-passwd=somepasswd -O - http://mysite.com/cgi-bin/pri/do_update.cgi

    5b. Don’t forget to give execution privilege to your file. Again, only the user can have write access to it.

    chmod 755 post-commit

    htpasswd Password Tutorial

    Password Tutorial
    If you would like to have a set of web pages that are protected, requiring a username/password to gain access, this tutorial will show you how to set it up. This is geared towards the Unix Apache httpd servers used on holly, lamar, and www.colostate.edu. If you are using another web server, you’ll need to check that server’s documentation to see how to do this.

    Steps to Password-protect a Directory
    First, create a subdirectory in your web area. For the sake of this tutorial, I have created the “protect” directory. Set the permissions on the directory so that the server has read/execute. I do this by using the local command chgrp-www to set the group to the www group. This is the group that the server runs under at Colorado State University for the lamar, holly and www servers. I have used the -sd flag which sets “set group id” for a directory. This will then force any files you create within the protect directory to the www group, so if you ftp files to this directory they will be automatically readable by the server but not by any other user on the system. I then cd into the protect directory.

    cd ~ric/public_html
    mkdir protect
    chmod g+r,g+x,o-r,o-x protect
    chgrp-www -sd protect
    cd protect

    Next you must create a .htaccess file inside the directory you want protected. You can use either the vi or pico editors on the supported systems mentioned above or ftp the file to this directory. If you are new to unix or know little about vi then I suggest you use the pico editor or ftp the .htaccess file. The command to edit with pico is “pico .htaccess”. The .htaccess file should contain the following lines. The items in bold are things you will want to change depending on the location of the AuthUserFile and content of AuthName.

    AuthUserFile /z/ric/secret/.htpasswd
    AuthGroupFile /dev/null
    AuthName "Ric's protected files"
    AuthType Basic

    require valid-user

    The AuthName is what the user will see when they’re prompted for a password – something to the effect of “Enter the username for Ric’s Protected files”. The AuthUserFile is location of the password file and should be not accessible with a url on the server for security reasons. This is a full unix path and the permissions should be set up like the “protect” directory using the chmod and chgrp-www commands above so the only one that can read this file is the owner and the server. To get the full path of a directory, cd to that directory and enter the command “pwd” to print the working directory path.

    Now you’ll have to set up the password file. You’ll need to use the htpasswd program. It is included with the Apache httpd server.

    First cd to the directory that contains the password file. In this example the password file is called .htpasswd and is in the directory /z/ric/secret/ as indicated by the AuthUserFile file entry in the .htaccess file. For every username you want to add to the password file, enter the following. (the -c is only required the first time; it indicates that you want to create the .htpasswd file).

    cd
    Read the rest of this entry »

    Basics of password protecting a directory

    Here’s the basics of password protecting a directory on your server.

    First, you need to create a password file. Exactly how you do this will vary depending on what authentication provider you have chosen. More on that later. To start with, we’ll use a text password file.

    This file should be placed somewhere not accessible from the web. This is so that folks cannot download the password file. For example, if your documents are served out of /usr/local/apache/htdocs you might want to put the password file(s) in /usr/local/apache/passwd.

    To create the file, use the htpasswd utility that came with Apache. This will be located in the bin directory of wherever you installed Apache. If you have installed Apache from a third-party package, it may be in your execution path.

    To create the file, type:

    htpasswd -c /usr/local/apache/passwd/passwords rbowen

    htpasswd will ask you for the password, and then ask you to type it again to confirm it:

    # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    New password: mypassword
    Re-type new password: mypassword
    Adding password for user rbowen

    If htpasswd is not in your path, of course you’ll have to type the full path to the file to get it to run. With a default installation, it’s located at /usr/local/apache2/bin/htpasswd

    Next, you’ll need to configure the server to request a password and tell the server which users are allowed access. You can do this either by editing the httpd.conf file or using an .htaccess file. For example, if you wish to protect the directory /usr/local/apache/htdocs/secret, you can use the following directives, either placed in the file /usr/local/apache/htdocs/secret/.htaccess, or placed in httpd.conf inside a <Directory /usr/local/apache/apache/htdocs/secret> section.

    AuthType Basic
    AuthName "Restricted Files"
    # (Following line optional)
    AuthBasicProvider file
    AuthUserFile /usr/local/apache/passwd/passwords
    Require user rbowen

    Let’s examine each of those directives individually. The AuthType directive selects that method that is used to authenticate the user. The most common method is Basic, and this is the method implemented by mod_auth_basic. It is important to be aware, however, that Basic authentication sends the password from the client to the server unencrypted. This method should therefore not be used for highly sensitive data, unless accompanied by mod_ssl. Apache supports one other authentication method: AuthType Digest. This method is implemented by mod_auth_digest and is much more secure. Most recent browsers support Digest authentication.

    The AuthName directive sets the Realm to be used in the authentication. The realm serves two major functions. First, the client often presents this information to the user as part of the password dialog box. Second, it is used by the client to determine what password to send for a given authenticated area.

    So, for example, once a client has authenticated in the "Restricted Files" area, it will automatically retry the same password for any area on the same server that is marked with the "Restricted Files" Realm. Therefore, you can prevent a user from being prompted more than once for a password by letting multiple restricted areas share the same realm. Of course, for security reasons, the client will always need to ask again for the password whenever the hostname of the server changes.

    The AuthBasicProvider is, in this case, optional, since file is the default value for this directive. You’ll need to use this directive if you are choosing a different source for authentication, such as mod_authn_dbm or mod_authn_dbd.

    The AuthUserFile directive sets the path to the password file that we just created with htpasswd. If you have a large number of users, it can be quite slow to search through a plain text file to authenticate the user on each request. Apache also has the ability to store user information in fast database files. The mod_authn_dbm module provides the AuthDBMUserFile directive. These files can be created and manipulated with the dbmmanage program. Many other types of authentication options are available from third party modules in the Apache Modules Database.

    Finally, the Require directive provides the authorization part of the process by setting the user that is allowed to access this region of the server. In the next section, we discuss various ways to use the Require directive.

    Letting more than one person in

    The directives above only let one person (specifically someone with a username of rbowen) into the directory. In most cases, you’ll want to let more than one person in. This is where the AuthGroupFile comes in.

    If you want to let more than one person in, you’ll need to create a group file that associates group names with a list of users in that group. The format of this file is pretty simple, and you can create it with your favorite editor. The contents of the file will look like this:

    GroupName: rbowen dpitts sungo rshersey

    That’s just a list of the members of the group in a long line separated by spaces.

    To add a user to your already existing password file, type:

    htpasswd /usr/local/apache/passwd/passwords dpitts

    You’ll get the same response as before, but it will be appended to the existing file, rather than creating a new file. (It’s the -c that makes it create a new password file).

    Now, you need to modify your .htaccess file to look like the following:

    AuthType Basic
    AuthName "By Invitation Only"
    # Optional line:
    AuthBasicProvider file
    AuthUserFile /usr/local/apache/passwd/passwords
    AuthGroupFile /usr/local/apache/passwd/groups
    Require group GroupName

    Now, anyone that is listed in the group GroupName, and has an entry in the password file, will be let in, if they type the correct password.

    There’s another way to let multiple users in that is less specific. Rather than creating a group file, you can just use the following directive:

    Require valid-user

    Using that rather than the Require user rbowen line will allow anyone in that is listed in the password file, and who correctly enters their password. You can even emulate the group behavior here, by just keeping a separate password file for each group. The advantage of this approach is that Apache only has to check one file, rather than two. The disadvantage is that you have to maintain a bunch of password files, and remember to reference the right one in the AuthUserFile directive.

    Because of the way that Basic authentication is specified, your username and password must be verified every time you request a document from the server. This is even if you’re reloading the same page, and for every image on the page (if they come from a protected directory). As you can imagine, this slows things down a little. The amount that it slows things down is proportional to the size of the password file, because it has to open up that file, and go down the list of users until it gets to your name. And it has to do this every time a page is loaded.

    A consequence of this is that there’s a practical limit to how many users you can put in one password file. This limit will vary depending on the performance of your particular server machine, but you can expect to see slowdowns once you get above a few hundred entries, and may wish to consider a different authentication method at that time.

    Alternate password storage

    Because storing passwords in plain text files has the above problems, you may wish to store your passwords somewhere else, such as in a database.

    mod_authn_dbm and mod_authn_dbd are two modules which make this possible. Rather than selecting AuthBasicProvider file, instead you can choose dbm or dbd as your storage format.

    To select a dbd file rather than a text file, for example:

    <Directory /www/docs/private>
    AuthName "Private"
    AuthType Basic
    AuthBasicProvider dbm
    AuthDBMUserFile /www/passwords/passwd.dbm
    Require valid-user </Directory>

    Other options are available. Consult the mod_authn_dbm documentation for more details.

    htpasswd information

    You should also read the documentation for mod_auth_basic and mod_authz_host which contain some more information about how this all works. mod_authn_alias can also help in simplifying certain authentication configurations.

    The various ciphers supported by Apache for authentication data are explained in Password Encryptions.

    And you may want to look at the Access Control howto, which discusses a number of related topics.