<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <meta name="Keywords" content="mod_auth_form apache apache2 form-based form based authentication authorization module mysql session group" /> <meta name="Description" content="Mod_auth_form performs form-based authorization using MySQL, session, and group management." /> <meta name="Author" content="Aaron Arthurs <ajarthu@uark.edu>" /> <meta name="Robots" content="all" /> <title>Apache2 Form-Based Authorization</title> <link rel="stylesheet" type="text/css" href="index.css" /> </head> <body> <center> <h1>Apache2 Module 'mod_auth_form'</h1> <h4><i>Current Version: 2.04</i></h4> </center> <h2>Contents</h2> <ul> <li><a href="#OVERVIEW">Overview</a></li> <li><a href="#REQUIREMENTS">Requirements</a></li> <li><a href="#DOWNLOADS">Downloads</a></li> <li><a href="#INSTALLATION">Minimum Installation and Configuration</a></li> <li><a href="#EXAMPLES">Examples</a></li> <ul> <li><a href="#EX_SIMPLE">A Simple Restricted Area</a></li> <li><a href="#EX_COMPLEX">A Complex Member's Area</a></li> <li><a href="#EX_LOGOUT">Logging Out</a></li> </ul> <li><a href="#REFERENCE">Configuration Reference</a></li> <li><a href="#IDEAS">Ideas for Future Releases</a></li> <li><a href="#CONTRIBUTE">Contributing</a></li> <li><a href="#CONTRIBUTORS">Contributors</a></li> <li><a href="#COPYRIGHT">Copyright</a></li> </ul> <hr /> <h2><a name="OVERVIEW"></a>Overview</h2> <div> This module is a form-based authorization module based on '<a href="http://www.heuer.org/mod_auth_mysql/">mod_auth_mysql</a>' and '<a href="http://www.perl-studio.com/mod_auth_sim/">mod_auth_sim</a>'. It is used to place access restrictions on a per-directory, per-user-request basis using session management. The module uses a MySQL database to retrieve users' group membership, maintain and validate users' sessions, and optionally track user activity. <br /><br /> The mechanics of the module works in the following way. A web client (user) requests for a restricted page/directory. The module sends back a 'Page Has Moved' error, pointing the client to the page containing a login form. Through server-side scripting, a session is created in the MySQL database and the client (i.e. cookies or query string). The session itself consists of a unique, random, and temporary ID that is associated with a user. The client then makes the same request along with the session ID (SID) and the user ID (UID). The module compares and validates the two IDs against the IDs stored in the MySQL database. If successful, the module sends back the requested page; otherwise, the module once again sends back the 'Page Has Moved' error page. In addition (if specified), the module will also validate the user's group membership and act accordingly. <br /><br /> <b>Additional Notes:</b> <br /> 1) This module does not verify username and passwords (not yet). The verification is left up to the web developer via server-side scripting. For example, if .htpasswd files are used, a Perl script can be written to verify a user's input against a .htpasswd file; if the user is verified, the same Perl script will create a session in the user's browser (cookies or query string) and in a MySQL database. <br /><br /> 2) Do not use Apache's basic authentication directives with this module (exceptions are 'AuthType Basic' and 'AuthName "Name"'). Doing so may cause Apache to use basic authentication whenever a user accesses a restricted page. (See <a href="http://httpd.apache.org/docs-2.0/mod/mod_auth.html">mod_auth</a> and similiar modules). <br /><br /> 3) To turn off 'mod_auth_form' for certain directories, add the directive "AuthFormAuthoritative Off" to the directory container. This is only useful when applying a different authentication module (e.g. mod_auth) to a directory under mod_auth_form's control (usually sub-directories). <br /><br /> 4) This module requires SELECT permission at minimum. For 'AuthFormSessionTimeout', UPDATE is also required. For the tracking table, the module also requires INSERT, DELETE, and UPDATE permissions. <br /><br /> 5) Enclose MySQL keywords with backticks (`) when using the 'AuthFormMySQL*' directives,. For example, "AuthFormMySQLFieldUID SELECT" needs to be "AuthFormMySQLFieldUID `SELECT`". <br /><br /> 6) Use caution when specifying a fixed number of seconds for AuthFormSessionAutoRefresh. This option does not work well with inline frames that point to other auto-refreshing documents. If you have a restricted page with inline frames, you may need to specify "AuthFormPageAutoRefresh mypage.html" for each framed document. <br /><br /> 7) 'AuthFormMySQLTableGID' should refer to a join table if each user is to be associated with multiple groups (where 'AuthFormMySQLFieldUID' and 'AuthFormMySQLFieldGID' are the join table attributes). Although this module allows multiple values for the 'AuthFormMySQLFieldGID' field, use only one value per record. This multi-value feature will be removed in the next major version (3.0). <br /><br /> 8) This module may be renamed to mod_authnz_form for the next major version (3.0). The next major version (and maybe the 2.x series) will support authentication via HTTP POST along with session management, hence the 'nz' after 'auth'. <br /> </div> <hr /> <h2><a name="REQUIREMENTS"></a>Requirements</h2> <ul> <li><a href="http://httpd.apache.org">Apache 2.0 Web Server</a></li> <li><a href="http://dev.mysql.com/downloads/">MySQL 4.1 or greater</a></li> <li>Server-Side Scripting Processor <ul> <li>Comes with MySQL-Capable API (optionally MySQLi)</li> <li><a href="http://www.rubyonrails.org">Ruby on Rails</a> looks promising</li> <li>Perhaps <a href="http://www.php.net/downloads.php">PHP 5/4</a></li> </ul> </ul> <h2><a name="DOWNLOADS"></a>Downloads</h2> <ul> <li>Version 2.04</li> <ul> <li><a href="download.php?download=v2_04%2Fmod_auth_form-2.04-src.tar.gz">Source Code</a> (<a href="download.php?download=v2_04%2Fmod_auth_form-2.04-src.tar.gz.md5">MD5SUM</a>)</li> <li><a href="download.php?download=v2_04%2Fmod_auth_form-2.04-win32.zip">Win32 Binaries</a> (<a href="download.php?download=v2_04%2Fmod_auth_form-2.04-win32.zip.md5">MD5SUM</a>)</li> <li>Bugs:</li> <ul> <li>BUG #7: MySQL SSL directives mismatch the internal data structure (see PATCH #4).</li> <li>BUG #8: Query string/cookie values are not decoded (see PATCH #6).</li> <li>BUG #9: The apostrophe from the query string/cookie values is not escaped (see PATCH #6).</li> </ul> <li>Patches:</li> <ul> <li>PATCH #3: <a href="download.php?download=v2_04/mod_auth_form-2.04-configure_apr_hooks.patch">apr/apr-util RPM include layout</a>: configure looks for apr_hooks.h instead of apr.h</li> <li>PATCH #4: <a href="download.php?download=v2_04/mod_auth_form-2.04-mysql_ssl_conf_mismatch_fix.patch">BUGFIX #7</a>: correct the MySQL SSL directive mismatch.</li> <li>PATCH #5: <a href="download.php?download=v2_04/mod_auth_form-2.04-mysql_ssl_check.patch">MySQL SSL Support Check</a>: check for mysql_ssl_set during configuration. Disable MySQL SSL support if not present.</li> <li>PATCH #6: <a href="download.php?download=v2_04/mod_auth_form-2.04-escape_value_apostrophe.patch">BUGFIX #8 and #9</a>: Decode query string/cookie values and escape the apostrophe if necessary.</li> </ul> <li>Changes:</li> <ul> <li>Fixed some Apache 2.2.x compatibility issues</li> <li>Added <b>AuthFormMySQLSocket</b></li> <li>Added MySQL SSL directives (mimics parameters in mysql_ssl_set)</li> <li>Now using libtool versioning</li> <li>'make install' no longer:</li> <ul> <li>Restarts the Apache2 server</li> <li>Edits the main configuration file</li> </ul> </ul> </ul> <li>Version 2.03</li> <ul> <li><a href="download.php?download=v2_03%2Fmod_auth_form-2.03-src.tar.gz">Source Code</a> (<a href="download.php?download=v2_03%2Fmod_auth_form-2.03-src.tar.gz.md5">MD5SUM</a>)</li> <li><a href="download.php?download=v2_03%2Fmod_auth_form-2.03-win32.zip">Win32 Binaries</a> (<a href="download.php?download=v2_03%2Fmod_auth_form-2.03-win32.zip.md5">MD5SUM</a>)</li> <li>Patches:</li> <ul> <li>PATCH #1: <a href="download.php?download=v2_03%2Fmod_auth_form-2.03-method_to_scheme.patch">ap_http_method to ap_http_scheme</a>: for compatibility with Apache 2.2.x</li> <li>PATCH #2: <a href="download.php?download=v2_03%2Fmod_auth_form-2.03-apr_1_fix.patch">APR-1 compatibility fix</a>: for compatibility with Apache 2.2.x</li> </ul> <li>Changes:</li> <ul> <li>BUGFIX #5: <b>AuthFormMySQLTableSIDCondition</b> can distinguish similiarly named variables (thanks again Andrei Nazarenko)</li> <li>BUGFIX #6: The module returns a Forbidden message if it cannot connect to the specified MySQL server</li> <li>Added <b>AuthFormMySQLPort</b></li> <li>Added <b>AuthFormSessionDelete</b></li> <li>The module is enabled if <b>AuthFormAuthoritative</b> is 'On' and the module's required directives are present</li> <li>Set some CGI environment variables</li> <li>The 'configure' script is friendlier</li> </ul> </ul> <li>Version 2.02</li> <ul> <li><a href="download.php?download=v2_02%2Fmod_auth_form-2.02-src.tar.gz">Source Code</a> (<a href="download.php?download=v2_02%2Fmod_auth_form-2.02-src.tar.gz.md5">MD5SUM</a>)</li> <li><a href="download.php?download=v2_02%2Fmod_auth_form-2.02-win32.zip">Win32 Binaries</a> (<a href="download.php?download=v2_02%2Fmod_auth_form-2.02-win32.zip.md5">MD5SUM</a>)</li> <li>Changes</li> <ul> <li>BUGFIX #3: Fixed 'AuthFormMySQLFieldGID' to default to 'gid'</li> <li>BUGFIX #4: 'AuthFormMySQLFieldGID' no longer needs specifying for the Require line (thanks Andrei Nazarenko) <li>Added auto-refresh feature</li> <li>Added 'last visited, unauthorized page' feature</li> <li>Extract GIDs from all (not just one) records with matching UID</li> </ul> </ul> <li>Version 2.01</li> <ul> <li><a href="download.php?download=v2_01%2Fmod_auth_form-2.01-src.tar.gz">Source Code</a> (<a href="download.php?download=v2_01%2Fmod_auth_form-2.01-src.tar.gz.md5">MD5SUM</a>)</li> <li><a href="download.php?download=v2_01%2Fmod_auth_form-2.01-win32.zip">Win32 Binaries</a> (<a href="download.php?download=v2_01%2Fmod_auth_form-2.01-win32.zip.md5">MD5SUM</a>)</li> <li>Changes</li> <ul> <li>BUGFIX #1: Fixed unwanted redirects to the login page (thanks Martin Daur)</li> <li>BUGFIX #2: Fixed 'lost' spaces in the variable parser</li> <li>Added variable parsing to 'AuthFormMySQLTable<GID,Tracking>Condition'</li> </ul> </ul> <li>Version 2.0</li> <ul> <li><a href="download.php?download=v2_0%2Fmod_auth_form-2.0-src.tar.gz">Source Code</a> (<a href="download.php?download=v2_0%2Fmod_auth_form-2.0-src.tar.gz.md5">MD5SUM</a>)</li> <li><a href="download.php?download=v2_0%2Fmod_auth_form-2.0-win32.zip">Win32 Binaries</a> (<a href="download.php?download=v2_0%2Fmod_auth_form-2.0-win32.zip.md5">MD5SUM</a>)</li> <li>Changes</li> <ul> <li>Removed directives 'AuthFormMySQLFieldSID', 'AuthFormSessionKeyUID', and 'AuthFormSessionKeySID'.</li> <li>Using 'AuthFormMySQLTableSIDConditon' for session validation.</li> <li>Set the priority higher (i.e. override other authentication modules).</li> </ul> </ul> <li><a href="v1_0">Version 1.0</a></li> </ul> <hr /> <h2><a name="INSTALLATION"></a>Minimum Installation and Configuration</h2> <div> Download the module and copy 'mod_auth_form.so' (and 'mod_auth_form.pdb' on win32) to the modules directory in the Apache2 distribution. Add the following lines to 'httpd.conf'. <br /><br /> <div class="clInfoBox"><pre> LoadModule auth_form_module modules/mod_auth_form.so # Directory and/or .htaccess statements AuthType Basic AuthName "Realm Name" # This has no effect, but it is required by Apache2. AuthFormMySQLDB MySQL_Database AuthFormPageLogin The_Login_Page_URL Require valid-user</pre> </div> <br /> Under MySQL, create the following. <ul> <li>Database: MySQL_Database</li> <ul> <li>Table: sessions</li> <ul> <li>Field: VARCHAR: sid (PRIMARY KEY)</li> <li>Field: VARCHAR: uid</li> </ul> </ul> </ul> Restart Apache2. <br /> </div> <hr /> <h2><a name="EXAMPLES"></a>Examples</h2> <div> <b><a name="EX_SIMPLE"></a>Case Study 1: A Simple Restricted Area:</b> A website will contain a restricted area that requires a valid username and password. The restricted area itself is a directory called '/restricted'; the login pages for that restricted directory are '/login.html' and its handler '/login.php'. The MySQL server resides on the same computer as the Apache server, and the name of the database is 'users'. To implement this restricted area, the following must be done: <ul> <li>httpd.conf</li> <div class="clInfoBox"><pre> LoadModule auth_form_module modules/mod_auth_form.so <Directory "/absolute/path/to/restricted"> AuthType Basic AuthName "Restricted" # AuthFormMySQLHost # localhost # AuthFormMySQLPort # Default port (3306) # AuthFormMySQLUsername # Use Apache's username # AuthFormMySQLPassword # Password-less login AuthFormMySQLDB users AuthFormSessionCookies On AuthFormPageLogin /login.html Require valid-user </Directory></pre> </div> <li>MySQL Database: users</li> <ul> <li>Table: sessions</li> <ul> <li>Field: VARCHAR (32): sid (PRIMARY KEY)</li> <li>Field: VARCHAR (20): uid (FOREIGN KEY)</li> </ul> <li>Table: passwords</li> <ul> <li>Field: VARCHAR (20): uid (PRIMARY KEY)</li> <li>Field: VARCHAR (32): password (MD5 CRYPTED)</li> </ul> </ul> <li>/login.html</li> <div class="clInfoBox"><pre> <html> <head> ... </head> <body> <form action="/login.php" method="post"> <input name="uid" type="text" maxlength="20"> <input name="password" type="password" maxlength="20"> <input type="submit" value="Login"> </form> </body> </html></pre> </div> <li>/login.php</li> <div class="clInfoBox"><pre> <?php function genID($seed, $length) { $ID = ""; srand($seed); for($i = 0; $i < $length; $i++) { $chtype = rand(1, 3); switch($chtype) { case 1: // 0-9 $ID .= chr(rand(48, 57)); break; case 2: // A-Z $ID .= chr(rand(65, 90)); break; case 3: // a-z $ID .= chr(rand(97, 122)); break; } } return $ID; } function create_session($mysql, $uid, $password) { // // Build list of existing SIDs // $result = $mysql->query("SELECT sid FROM sessions"); $num_rows = $result->num_rows; while($num_rows > 0) { $row = $result->fetch_assoc(); $sids[$row["sid"]] = TRUE; $num_rows--; } $result->close(); // // Generate SID (making sure it is unique) // $max_attempts = 500000; $seed = crc32($password); do { $sid = genID($seed + time(), 32); $max_attempts--; } while(isset($sids[$sid]) && $max_attempts > 0); if($max_attempts <= 0) // NOT GOOD return FALSE; // // Create the session: set the UID and SID in both the client's cookies and // the MySQL session table. // $mysql->query("INSERT INTO sessions (sid, uid) VALUES ('$sid', '$uid')"); setcookie("uid", $uid, time() + 964224000); setcookie("sid", $sid, time() + 964224000); return TRUE; } $uid = $_POST["uid"]; $password = $_POST["password"]; $mysql = new mysqli("localhost", "my_username", "my_password", "users"); $result = $mysql->query("SELECT password FROM passwords WHERE uid='$uid'"); $row = $result->fetch_assoc(); $real_password = $row["password"]; $result->close(); if(md5($password) == $real_password) { create_session($mysql, $uid, $real_password); header("Location: /restricted"); } $mysql->close(); ?></pre> </div> </ul> <b><a name="EX_COMPLEX"></a>Case Study 2: A Complex Member's Area:</b> A website will contain a member's area that requires a valid username and password. The member's area itself is a directory called '/members'; furthermore, there are two more restricted directories called '/members/paying', which is for paying members only (where as '/members' is for any member) and '/members/paying/premium', which is for buisness customers and/or premium members. For added security, all sessions will expire either from 30 minutes of inactivity or 8 hours from the time of login; also, sessions are valid if two SID cookies matches and either the UID cookie or the directory's signature matches (in case the UID cookie is rejected). The login pages for the member's area are '/member_login.html' and its handler '/member_login.php'. The MySQL server resides on a host called 'fake_server.com', and the name of the database is 'members'. Also, the MySQL server will keep tracking records of each request made within the member's area. <br /><br /> For additional complexity, another directory called '/administration' will be accessed locally by the website maintainers. This directory will use basic authentication from 'mod_auth' using a password file located at '/absolute/path/to/passwords'. <br /><br /> To implement this member's area, the following must be done:<br /> <ul> <li>httpd.conf</li> <div class="clInfoBox"><pre> LoadModule auth_form_module modules/mod_auth_form.so <Directory "/absolute/path/to/members"> AuthType Basic AuthName "Member's Area" AuthFormMySQLHost fake_server.com AuthFormMySQLUsername my_username AuthFormMySQLPassword my_password AuthFormMySQLDB members AuthFormMySQLTableGID uid_gid AuthFormMySQLTableSIDCondition "`sid`=$sid1 AND `sid_dir`=$sid2\ AND (`uid`=$uid OR `signature`='some_signature_members')" AuthFormMySQLTableTracking tracking AuthFormMySQLFieldExpiration expiration_date AuthFormLastPageKey go_back_to AuthFormSessionTimeout 30 #minutes AuthFormSessionCookies On AuthFormPageLogin /member_login.html AuthFormPageExpired /session_expired.html Require group 0 1 #non-paying paying </Directory> <Directory "/absolute/path/to/members/paying"> AuthFormPageNotAllowed /paying_members_only.html AuthFormMySQLTableSIDCondition "`sid`=$sid1 AND `sid_dir`=$sid2\ AND (`uid`=$uid OR `signature`='some_signature_paying')" Require group 1 #paying </Directory> <Directory "/absolute/path/to/members/paying/premium"> AuthFormPageNotAllowed /premium_only.html Require group 2 #premium </Directory> <Directory "/absolute/path/to/administration"> AuthType Basic AuthName "Administration" AuthUserFile /absolute/path/to/passwords # Turn off 'mod_auth_form' in this directory, # giving control to 'mod_auth'. AuthFormAuthoritative Off Allow from 127.0.0.1 # localhost Deny from all Order Deny,Allow Require valid-user </Directory></pre> </div> <li>MySQL Database: members</li> <ul> <li>Table: sessions</li> <ul> <li>Field: VARCHAR (32): sid (PRIMARY KEY)</li> <li>Field: VARCHAR (32): sid_dir</li> <li>Field: INT (8) UNSIGNED: uid (FOREIGN KEY)</li> <li>Field: VARCHAR (20): signature</li> <li>Field: DATETIME: timeout_date</li> <li>Field: DATETIME: expiration_date</li> </ul> <li>Table: creds</li> <ul> <li>Field: INT (8) UNSIGNED: uid (PRIMARY KEY)</li> <li>Field: VARCHAR (20): username (UNIQUE)</li> <li>Field: VARCHAR (32): password_md5</li> <li>Other fields describing each user...</li> </ul> <li>Table: groups</li> <ul> <li>Field: INT (8) UNSIGNED: gid (PRIMARY KEY)</li> <li>Field: VARCHAR (20): groupname</li> <li>Other fields describing each group...</li> </ul> <li>Table: uid_gid</li> <ul> <li>Field: INT (8) UNSIGNED: uid (FOREIGN KEY)</li> <li>Field: INT (8) UNSIGNED: gid (FOREIGN KEY)</li> </ul> <li>Table: tracking</li> <ul> <li>Field: INT (8) UNSIGNED: uid (FOREIGN KEY)</li> <li>Field: VARCHAR (15): client_ip_address</li> <li>Field: DATETIME: download_date</li> <li>Field: VARCHAR (255); download_path</li> <li>Field: INT (8) UNSIGNED: download_size</li> </ul> </ul> <li>/member_login.php</li> <div class="clInfoBox"><pre> <?php // // Assume the function 'genID' from the previous case study is defined. // function create_session($mysql, $uid, $password) { // // Build list of existing SIDs // $result = $mysql->query("SELECT sid FROM sessions"); $num_rows = $result->num_rows; while($num_rows > 0) { $row = $result->fetch_assoc(); $sids[$row["sid"]] = TRUE; $num_rows--; } $result->close(); // // Generate main SID (making sure it is unique) // $max_attempts = 500000; $seed = crc32($password); do { $sid1 = genID($seed + time(), 32); $max_attempts--; } while(isset($sids[$sid1]) && $max_attempts > 0); if($max_attempts <= 0) // NOT GOOD return FALSE; $sid2 = genID(crc32($sid1) + time(), 32); // // Create the session: set the UID and SID in both the client's cookies and // the MySQL session table. // $mysql->query("INSERT INTO sessions (sid, sid_dir, uid, signature, timeout_date, expiration_date) VALUES ('$sid1', '$sid2', '$uid', 'some_signature_members', DATE_ADD(NOW(), INTERVAL 30 MINUTE), DATE_ADD(NOW(), INTERVAL 8 HOUR))"); setcookie("sid1", $sid1, time() + 964224000); setcookie("sid2", $sid2, time() + 964224000); setcookie("uid", $uid, time() + 964224000); return TRUE; } $username = $_POST["username"]; $password = $_POST["password"]; $mysql = new mysqli("fake_server.com", "my_username", "my_password", "members"); $result = $mysql->query("SELECT uid,password_md5 FROM creds WHERE username='$username'"); $row = $result->fetch_assoc(); $uid = $row["uid"]; $real_password = $row["password_md5"]; $result->close(); if(md5($password) == $real_password) { create_session($mysql, $uid, $real_password); header("Location: /members"); } $mysql->close(); ?></pre> </div> </ul> <b><a name="EX_LOGOUT"></a>Logging Out:</b> Besides session expiration, logging out of a session is done simply by deleting the session's record from the MySQL database. In addition, the client's cookies can be expired if cookies are used. Here is a PHP script for destroying a session, assuming the client passes the session cookies. <div class="clInfoBox"><pre> <?php $uid = $_COOKIE["uid"]; $sid = $_COOKIE["sid"]; $mysql = new mysqli("mysql_host", "my_username", "my_password", "my_database"); $mysql->query("DELETE FROM sessions WHERE sid='$sid'"); $mysql->close(); setcookie("uid", $uid, time() - 964224000); setcookie("sid", $sid, time() - 964224000); header("Location: login_page"); ?></pre> </div> </div> <hr /> <h2><a name="REFERENCE"></a>Configuration Reference</h2> <h3>The directives listed below have the prefix <big>AuthForm</big>.</h3> <div> <div class="clConfName">Authoritative</div> <div class="clConfSyn">Flag : DEFAULT="On"</div> <div class="clConfDesc"> Turn on 'mod_auth_form'. </div> <br /> <div class="clConfName">LastPageKey (version 2.02+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The name of the url query string key containing the URL that a client unsuccessfully accessed (i.e. the URL from which the client was redirected). </div> <br /> <div class="clConfName">MySQLDB</div> <div class="clConfSyn">String : REQUIRED</div> <div class="clConfDesc"> The MySQL database to connect to. </div> <br /> <div class="clConfName">MySQLFieldDownloadDate</div> <div class="clConfSyn">String : DEFAULT="download_date"</div> <div class="clConfDesc"> Field under the tracking table that stores the time of request. </div> <br /> <div class="clConfName">MySQLFieldDownloadPath</div> <div class="clConfSyn">String : DEFAULT="download_path"</div> <div class="clConfDesc"> Field under the tracking table that stores the path of request. </div> <br /> <div class="clConfName">MySQLFieldDownloadSize</div> <div class="clConfSyn">String : DEFAULT="download_size"</div> <div class="clConfDesc"> Field under the tracking table that stores the size of request. </div> <br /> <div class="clConfName">MySQLFieldExpiration</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> Field under the session table that stores the time the session will expire regardless of user activity. Not specifying this configuration disables session expiration (although session inactivity timeout can still be enabled). Also, <b>AuthFormPageExpired</b> must be configured. </div> <br /> <div class="clConfName">MySQLFieldGID</div> <div class="clConfSyn">String : DEFAULT="gid"</div> <div class="clConfDesc"> Field under the group table that stores the user's space/comma delimited list of group IDs. <b><br />NOTE: Having a multi-value field violates the conceptual design of relational databases. In the next major version (3.0), this feature will be removed in favor of a join table.</b> </div> <br /> <div class="clConfName">MySQLFieldIPAddress</div> <div class="clConfSyn">String : DEFAULT="client_ip_address"</div> <div class="clConfDesc"> Field under the tracking table that stores the client's IP address. </div> <br /> <div class="clConfName">MySQLFieldTimeout</div> <div class="clConfSyn">String : DEFAULT="timeout_date"</div> <div class="clConfDesc"> Field under the session table that stores the time the session will expire if the user is inactive. </div> <br /> <div class="clConfName">MySQLFieldUID</div> <div class="clConfSyn">String : DEFAULT="uid"</div> <div class="clConfDesc"> Field under the session, group, and tracking tables that stores the user ID. </div> <br /> <div class="clConfName">MySQLHost</div> <div class="clConfSyn">String : DEFAULT="localhost"</div> <div class="clConfDesc"> The fully-qualified name or IP address of the MySQL server. </div> <br /> <div class="clConfName">MySQLPassword</div> <div class="clConfSyn">String : DEFAULT=<Blank Password></div> <div class="clConfDesc"> The MySQL user's password. </div> <br /> <div class="clConfName">MySQLPort (version 2.03+)</div> <div class="clConfSyn">Number : DEFAULT="3306"</div> <div class="clConfDesc"> The MySQL port to connect to. </div> <br /> <div class="clConfName">MySQLSSL (version 2.04+)</div> <div class="clConfSyn">Flag : DEFAULT="Off"</div> <div class="clConfDesc"> Use SSL connections to MySQL. Please see the <b>AuthFormMySQLSSL*</b> directives. Those directives mimic the parameters in mysql_ssl_set() from the MySQL Client API. </div> <br /> <div class="clConfName">MySQLSSLCA (version 2.04+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The path to the file listing the trusted certificate authorities. </div> <br /> <div class="clConfName">MySQLSSLCAPath (version 2.04+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The path to the directory containing the PEM-formatted, trusted certificate authorities. </div> <br /> <div class="clConfName">MySQLSSLCert (version 2.04+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The path to the MySQL client certificate. </div> <br /> <div class="clConfName">MySQLSSLCipherList (version 2.04+)</div> <div class="clConfSyn">String : DEFAULT="!ADH:RC4+RSA:HIGH:MEDIUM:LOW:EXP:+SSLv2:+EXP"</div> <div class="clConfDesc"> The list of SSL ciphers (in 'openssl ciphers' format) to allow for SSL connections. </div> <br /> <div class="clConfName">MySQLSSLKey (version 2.04+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The path to the MySQL client certificate key. </div> <br /> <div class="clConfName">MySQLSocket (version 2.04+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The path to the MySQL server socket file (Unix only). </div> <br /> <div class="clConfName">MySQLTableGID</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The table that stores the group memberships. <b>AuthFormMySQLFieldGID</b> and <b>AuthFormPageNotAllowed</b> must also be configured along with the <b>Require</b> directive in a directory container (refer the the <a href="http://httpd.apache.org/docs-2.0/"> Apache2 documentation</a> for more information). Also, the table must have a UID and GID field where the UID field is the primary key. </div> <br /> <div class="clConfName">MySQLTableGIDCondition</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> Condition to add to the WHERE-clause when querying the group membership table. </div> <br /> <div class="clConfName">MySQLTableSID</div> <div class="clConfSyn">String : DEFAULT="sessions"</div> <div class="clConfDesc"> The table that stores session records. At minimum, the table should have a SID field and a UID field where the SID field is the primary key. </div> <br /> <div class="clConfName">MySQLTableSIDCondition</div> <div class="clConfSyn">String : DEFAULT="sid=$sid AND uid=$uid"</div> <div class="clConfDesc"> Session validation condition used in the WHERE-clause when querying the session table. The variable placeholders (denoted as $var) store session values passed by the clients and validated by the module. With the exception of the placeholders, the syntax of the condition is the same as the syntax in a MySQL WHERE clause. </div> <br /> <div class="clConfName">MySQLTableTracking</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The table that stores request tracking information. The table must have a field for UID, client's IP address, download date, download path, and download size (no primary keys). </div> <br /> <div class="clConfName">MySQLTableTrackingCondition</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> Condition to add to the WHERE-clause when querying the tracking table. </div> <br /> <div class="clConfName">MySQLUsername</div> <div class="clConfSyn">String : DEFAULT=<Apache2 Username></div> <div class="clConfDesc"> The MySQL user used to connect to the MySQL server. </div> <br /> <div class="clConfName">PageAutoRefresh (version 2.02+)</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The URL to which to auto-refresh. Effectively speaking, this directive defaults to the current page if session expiration is disabled and/or not used (see <b>AuthFormSessionAutoRefresh</b>). Otherwise, this directive defaults to <b>AuthFormPageExpired</b>. </div> <br /> <div class="clConfName">PageExpired</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The URL to the 'session expired' page. </div> <br /> <div class="clConfName">PageLogin</div> <div class="clConfSyn">String : REQUIRED</div> <div class="clConfDesc"> The URL to the page containing the login form. </div> <br /> <div class="clConfName">PageNotAllowed</div> <div class="clConfSyn">String : OPTIONAL</div> <div class="clConfDesc"> The URL to the 'invalid group member' page. </div> <br /> <div class="clConfName">SessionAutoRefresh (version 2.02+)</div> <div class="clConfSyn">Number : DEFAULT=-1</div> <div class="clConfDesc"> How many seconds should the web browser refresh to a certain page (if not the current page). A value of 0 means disable auto-refreshing. A value of -1 (default) means auto-refresh when the client's session expires; if session expiration is disabled, auto-refreshing will effectively be disabled. Any value greater than 0 indicates a fixed number of seconds to auto-refresh. See also <b>AuthFormPageAutoRefresh</b>. </div> <br /> <div class="clConfName">SessionCookies</div> <div class="clConfSyn">Flag : DEFAULT="Off"</div> <div class="clConfDesc"> Whether to use cookies or the URL query string to pass the session keys from the client to the module. ('On' means use cookies; 'Off' means use the URL query string). </div> <br /> <div class="clConfName">SessionDelete (version 2.03+)</div> <div class="clConfSyn">Flag : DEFAULT="Off"</div> <div class="clConfDesc"> Whether or not the module should delete expired sessions per request.<br /> <b>NOTE: This feature is not as robust as managing expired sessions via server-side scripting, especially when auto-refreshing is used.</b> </div> <br /> <div class="clConfName">SessionTimeout</div> <div class="clConfSyn">Number : DEFAULT=0</div> <div class="clConfDesc"> The session inactivity timeout in minutes. A value of '0' indicates no timeout. Also, <b>AuthFormPageExpired</b> must be configured. </div> <br /> <div class="clConfName">TrackingLifetime</div> <div class="clConfSyn">Number : DEFAULT=30</div> <div class="clConfDesc"> Maximum number of days to hold a tracking record. A value of '0' indicates infinite lifetime. (The module goes by the date of download field under the tracking table). </div> <br /> </div> <hr /> <h2><a name="IDEAS"></a>Ideas for Future Releases</h2> <ul> <li>Add username/password verification support (e.g. verify against htpasswd files)</li> <li>Add support for other SQL servers (e.g. PostgreSQL)</li> <li>Add support for LDAP and flat files (XML) as a means for session tracking</li> <li>Somehow condense the module's directives</li> <li>Centralize database configurations</li> <li>Give a full URI from <b>AuthFormSessionLastPageKey</b> when necessary; otherwise, give a relative URI (maybe with a directive)</li> <li>Remove the multi-value feature of <b>AuthFormMySQLFieldGID</b> in favor of a join table</li> <li>Replace the "Examples" section with a demo-site</li> </ul> <h2><a name="CONTRIBUTE"></a>Contributing</h2> <div> Anybody who wants to contribute to this project may send me an email at <a href="mailto:ajarthu@uark.edu">ajarthu@uark.edu</a>. Before doing so, please read through <a href="#IDEAS">Ideas for Future Releases</a>. When sending source code, either attach a snippet of what's not in the module's source code or a patch. Along with the source code, please include a description in the email message. All source code must be in C. Testers are welcome to send their results (e.g. how many sessions can this module handle, security holes, etc). <br /><br /> Currently, I'm looking for support in obtaining the username and password through HTTP POST and maintaining persistent data in other backends besides MySQL. I'm thinking about adding options to the 'configure' script to specify which backend(s) to compile into the module. <br /><br /> One final note: Let me know if you want me to include your name and/or email address under the <a href="#CONTRIBUTORS">contribution list</a>. </div> <h2><a name="CONTRIBUTORS"></a>Contributors</h2> <ul> <li>Aaron Arthurs <ajarthu@uark.edu> (maintainer)</li> <li>Andrei Nazarenko <a.nazarenko@gmail.com></li> <li>Martin Daur <m.daur@beam.ag></li> <li>Matthew Dickinson <matt@alpha345.com></li> </ul> <hr /><a name="COPYRIGHT"></a> <div class="clCopyright"> Copyright 2004-2006 <a href="http://csce.uark.edu/~ajarthu">Aaron Arthurs</a><br /><br /> Licensed under the Apache Lincense, Version 2.0 (the "License");<br /> you may not use this file except in compliance with the License.<br /> You may obtain a copy of the License at<br /><br /> <div><a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSES-2.0</a><br /><br /></div> Unless required by applicable law or agreed to in writing, software<br /> distributed under the License is distributed on an "AS IS" BASIS,<br /> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br /> See the License for the specific language governing permissions and<br /> limitations under the License. </div> <hr /> Last Updated: Sat Jul 22 12:00:05 CDT 2006 <hr /> </body> </html>