]> granicus.if.org Git - pwauth/commitdiff
Migrating wiki contents from Google Code wiki
authorGoogle Code Exporter <GoogleCodeExporter@users.noreply.github.com>
Fri, 24 Apr 2015 14:31:53 +0000 (10:31 -0400)
committerGoogle Code Exporter <GoogleCodeExporter@users.noreply.github.com>
Fri, 24 Apr 2015 14:31:53 +0000 (10:31 -0400)
FormAuth.md [new file with mode: 0644]
InstallApache.md [new file with mode: 0644]
InstallMain.md [new file with mode: 0644]
InstallNotes.md [new file with mode: 0644]
Introduction.md [new file with mode: 0644]
ProjectHome.md [new file with mode: 0644]
Risks.md [new file with mode: 0644]
StatusCodes.md [new file with mode: 0644]
TableOfContents.md [new file with mode: 0644]

diff --git a/FormAuth.md b/FormAuth.md
new file mode 100644 (file)
index 0000000..6c70f42
--- /dev/null
@@ -0,0 +1,39 @@
+# Pwauth with Form Authentication #
+
+Although pwauth was designed for use with the mod\_auth\_external Apache module to do "Basic Authentication", it can also be used with "Form Authentication".
+
+In "Form Authentication" you display a login form in HTML, like
+```
+<form action="login.cgi" method="post">
+Login:    <input type="text" name="login"><br>
+Password: <input type="password" name="passwd"><br>
+<input type="submit" value="Login Now">
+</form>
+```
+
+When a person submits this form, the "login.cgi" program gets run.  It checks the login and password, and if they are correct, initiates a session for the user.  See [my authentication pages](http://unixpapa.com/auth/) for more information about this, including explanations about why it is important for good security to use `method="post"`, and to turn off caching both on the login form page and on the first page transmitted after a successful login.
+
+It is possible to use pwauth (or any other authenticator written for mod\_auth\_external) with this kind of authentication system.  All you have to do is have your CGI program run pwauth when it wants to check the password.
+
+Here's a sample function in Perl that does exactly this.  The 'trypass()' function will return the same [status codes](StatusCodes.md) that pwauth does (_ie_, zero on success, other values on failure).
+```
+$pwauth_path= "/usr/local/libexec/pwauth";
+
+sub trypass {
+   my $userid= $_[0];
+   my $passwd= $_[1];
+
+   open PWAUTH, "|$pwauth_path" or die("Could not run $pwauth_path");
+   print PWAUTH "$userid\n$passwd\n";
+   close PWAUTH;
+   return !$?;
+}
+```
+
+Obviously the `$pwauth_path` should be defined to wherever you install pwauth, and the `die()` call should be replaced with whatever is an appropriate way to handle a fatal error in your CGI program.
+
+Note that pwauth must be configured so that SERVER\_UIDS includes whatever uid your CGI program runs as.  Normally this is the same user ID that httpd runs as, but if your CGIs are running under suExec, then you may need to include other uid numbers.
+
+You may want to examine the return code from pwauth more carefully than is done in this example, so that you can tell the user if his login was rejected due to logins being turned off, his account being expired, or his password being expired.  Though in some configurations pwauth will return different return codes for bad password and bad login name, it is generally considered good practice NOT to tell the user which of these two occurred.
+
+From a security point of view, form-based authentication has pluses and minuses.  Mostly in such approaches you will be assigning session IDs to logged in users (see my [authentication guide](http://www.unixpapa.com/auth/) for details).  This has the advantage that you can provide logout buttons and idle timeouts, neither of which is possible with basic authentication.  The ability for users to log out is a considerable improvement to security. However, those session IDs are frequently passed around in cookies, which can have some security problems if you ever have untrusted users on your server.  Cookies are passed to CGI programs in environment variables, and many older Unix systems allow other users to see a process's environment variables.
\ No newline at end of file
diff --git a/InstallApache.md b/InstallApache.md
new file mode 100644 (file)
index 0000000..3559754
--- /dev/null
@@ -0,0 +1,53 @@
+# Configuring Apache #
+
+If  you want to use pwauth for basic authentication in Apache, then you will need to use mod\_authnz\_external or, if you are using an old version of Apache, mod\_auth\_external.
+
+## 1. Install the module ##
+
+You need version 2.1.1 or later of [mod\_auth\_external](http://code.google.com/p/mod-auth-external/) or [mod\_authnz\_external](http://code.google.com/p/mod-auth-external/).  See the installation instructions in that distribution for details.
+
+## 2. Server Configuration ##
+
+Find the Apache server configuration file.  In the old days it was called httpd.conf.  These days it may be a directory full of miscellaneous files and you may have to do some digging to find the right place to insert local configuration commands.  In OpenSuse, for example, you'd create a new file under /etc/apache2/conf.d containing these commands.
+
+Insert the following lines:
+```
+AddExternalAuth pwauth /usr/local/libexec/pwauth
+SetExternalAuthMethod pwauth pipe
+```
+Obviously if you used a different path for pwauth, you should use that path instead.
+
+## 3. Directory Configuration ##
+
+Put an .htaccess file in whatever directory you want to protect. (For .htaccess files to work, you may need to change some "`AllowOverride None`" directives in your httpd.conf file into "`AllowOverride AuthConfig`" directives).
+
+A typical .htaccess file using mod\_authnz\_external would look like:
+```
+AuthType Basic
+AuthName Your-Site-Name
+AuthBasicProvider external
+AuthExternal pwauth
+require valid-user
+```
+A typical .htaccess file using mod\_auth\_external would look like:
+```
+AuthType Basic
+AuthName Your-Site-Name
+AuthExternal pwauth
+require valid-user
+```
+
+Alternately, you could put these directives in a `<Directory>` block in your httpd.conf file.
+
+If you want to allow users of only certain Unix groups to login, the perl "unixgroup" command included in this directory will do the job, though not very efficiently.  If you are using mod\_authnz\_external, a better approach is to use [mod\_authz\_unixgroup](http://unixpapa.com/mod_authz_unixgroup/).  This will not only allow you to restrict logins to users in particular groups, but restrict access to individual files based on group ownership of the files, if used with the standard Apache module mod\_authz\_owner.
+
+## 4. Test ##
+
+Test it by trying to access a file in the protected directory with your web browser.
+
+If it fails to accept correct logins, then check Apache's error log file.  This should give some messages explaining why authentication failed.
+
+If it was unable to execute pwauth, check that the pathnames and permissions are all correct.
+
+If it says that pwauth failed, it will give the numeric status code that pwauth returned.
+The [status code page](StatusCodes.md) tells the meaning of all these codes.
\ No newline at end of file
diff --git a/InstallMain.md b/InstallMain.md
new file mode 100644 (file)
index 0000000..f6bc2ef
--- /dev/null
@@ -0,0 +1,164 @@
+# Installation Instructions #
+
+Before installing pwauth, please be sure that you have read and understood the [Risks](Risks.md) page.  This is not a tool that is appropriate for every server.
+
+## 1. Edit config.h ##
+
+All configuration of pwauth is done via the config.h file.  You should set or check the following variables:
+
+### 1.1. Authentication Method ###
+
+What API should authentication be done through?  The most common options are:
+
+  * SHADOW\_SUN:  This is the shadow password system in Solaris, Linux and IRIX 5.3 systems.  It uses getspnam() to fetch passwords and crypt() to encrypt them.
+
+  * SHADOW\_BSD: This is the shadow password system in BSDI, NetBSD, OpenBSD, and FreeBSD.  This uses getpwnam() to fetch passwords and crypt() to encrypt them.  This would only work with OS X if the accounts being authenticated are configured with legacy crypt style passwords.  In general, the PAM option is more likely to be usable in OS X.
+
+  * PAM: Talk to the authentication system through PAM - the plug-in authentication module interface.  This exists on Linux, Solaris 7, FreeBSD, and OS X.  You'll need to create /etc/pam.d/pwauth or edit /etc/pam.config to include entries for pwauth.  If you are using PAM to authenticate out of something you don't need to be root to access, then you might use instead Ingo Lutkebohle's mod\_auth\_pam.c module.  If you are using Solaris, you may need to use PAM\_SOLARIS or PAM\_SOLARIS\_26 instead to work around various bugs.
+
+  * LOGIN\_CONF\_OPENBSD:  Many BSD derived systems use a login.conf file to configure authentication instead of (or in addition to) PAM.  We currently support authentication through this mechanism only for OpenBSD.  Of course, if you login.conf configuration is standard, you can just use SHADOW\_BSD, but if you want pwauth to respect settings in login.conf this option can be used instead.  The API used here, is however, pretty much unique to OpenBSD and will not work on NetBSD or FreeBSD.
+
+There are several other more obscure methods used which are documented in the config.h file.
+
+In most cases the method that you want if you just want to authenticate from the system password file is SHADOW\_SUN or SHADOW\_BSD depending on your Unix version.  PAM is slower and more complex to set up, but allows greater flexibility in configuration and allows you to authenticate from other sources.
+
+### 1.2. Failure Logging ###
+
+A failure log keeps a count of how many bad logins have been attempted for each user,
+and disables logins to any account where some limit is exceeded.  This is useful to
+prevent people from trying to guessing passwords by trying every word in the dictionary, but it can be a problem because it means anyone can disable any user account just by trying some bad passwords on it.
+
+A few Unix systems, like OpenBSD, have failure logs for normal logins to the system, and pwauth can be configured to tie into them.  But it is also possible to set up pwauth to use it's own failure log even on systems that don't have one for normal logins.
+
+If you choose to use this, it would probably be good to have your CGI's run the "checkfaillog" program after successful logins to report the count of bad logins and to reset the count to zero.
+
+I think most installations don't use this and it should not be enabled with PAM, which performs this function at a lower level.
+
+
+### 1.3. Lastlog Logging ###
+
+Nearly all Unix systems maintain a lastlog file that keeps record of the last time that each user logged into the system.  It is possible to have pwauth update this when successful authentications occur.  This can be important on systems where you expire unused accounts and some users may only log in via the web.
+
+This should not be enabled with PAM, where this is done at a lower level.
+
+### 1.4. /etc/nologin ###
+
+Most Unix systems will refuse logins if the file /etc/nologin exists.  It is normal to configure pwauth to also refuse logins if that file exists.  Alternately you could set it up to have a separate file to disable pwauth logins simply by giving a different path name in the configuration.  Again, this should not be used with PAM.
+
+### 1.5. Login/Password Expiration ###
+
+Most modern Unix systems allow administrators to set dates at which accounts expire and can no longer be used, or at which passwords expire and must be changed.  Sometimes administrators use these features to temporarily disable accounts that should not be usable.  So it is almost always advisable to have pwauth respect these settings.  If your administrators don't use these features, there is no harm, but if they do, they should be respected.
+
+### 1.6. Who May Run Pwauth? ###
+
+It is generally sensible to restrict what users can run pwauth.  Though there are other programs that users can use to test if password guessesare correct, like "su" and "passwd", pwauth is much easier to interface a password guessing program to, so why not be paranoid and restrict it as much as possible?
+
+If you are using pwauth with mod\_auth\_external, you will want to restrict it to be runnable from whatever uid your httpd runs as.  (For apache, this is determined by the "User" directive in your httpd.conf file.  It may be called something like "nobody" or "httpd" or "apache".  Usually the easiest way to figure it out is just to do a "ps" and see what most apache processes are running as.)
+
+There are two ways to do this.  First, you can compile in the uid numbers that are allowed to run this program, by listing them on the SERVER\_UID variable below.  At runtime, pwauth will check that the uid of the user that invoked it is on this list.  So if you have just one uid that should be able to run pwauth, you can say something like:
+```
+   #define SERVER_UIDS 72
+```
+If you have several, separate them by commas, like this:
+```
+   #define SERVER_UIDS 12,343,93
+```
+The root account can always run this program, so you don't have to to list that.  If you do list it, it must be given last.
+
+The second option is to create a special group, called something like "pwauth" for user id's that are allowed to run pwauth.  To do this, you should compile pwauth with the SERVER\_UIDS variable UNDEFINED.  This will disable the runtime uid check.  Then, when you install the pwauth program, set it's group ownership to the "pwauth" group, and permit it so that only the owner and the group can run it.  Do not permit it to be executable to others.  This has the advantage of not requiring a recompile if you want to change the uid list.  If you are thinking of distributing pwauth as a precompiled package, then this might be your best option.
+
+### 1.7. Minimum User Id ###
+
+Typically we don't want to let people use pwauth to log into the "root" account or any other administrative accounts. Those administrative accounts usually have lower numbered user IDs than regular user accounts.  So you can defined MIN\_UNIX\_UID to reject any logins to accounts with user id numbers below a certain value.
+
+### 1.8. Case Sensitivity and Domain Awareness ###
+
+The IGNORE\_CASE flag causes every login ID to be checked two ways - first as given, then with all uppercase characters converted to lowercase.  This is useful if your site has many habitual Windows users who may be accustomed to login IDs not being case sensitive.  It really only "ignores case" if the actual IDs on your server are all lower case though.
+
+In some environments you may also have windows users accustomed to login names formed like "domain\username".  In such cases, you can set the DOMAIN\_AWARE flag, and pwauth will check each login name to see if it contains a backslash, and, if so, discard the backslash and everything before it.
+
+### 1.9. Sleep Lock ###
+
+When you are logging into a unix system at the "Login:" prompt, you will notice that if you enter an incorrect password, then there is a delay of a few seconds before you are prompted for a new one.  This is to prevent password guessing programs from submitting huge numbers of password guesses quickly.  This is harder to do in a web environment, however, since many http requests can be made simultaneously.
+
+Pwauth handles this problem by sleeping for SLEEP\_TIME seconds after each failed authentication, using a lock on the file whose full path is given by SLEEP\_LOCK to prevent any other instances of pwauth from running during that time.  The default settings for these options should be suitable for most systems.
+
+In theory this could be a performance problem on extremely heavily used system, though I have never heard of anyone having problems with this.
+
+### 1.10. Argument Passing ###
+
+Normally the login and password are passed to pwauth through a pipe.  This method is secure on all versions of Unix.  It is possible to configure pwauth to instead take its arguments from environment variables, but this is not recommended because on some versions of Unix it is possible to other users to eavesdrop on a processes environment variable settings, and we do not want user's plain text passwords to be readily visible.
+
+## 2. Edit Makefile ##
+
+Edit the Makefile, and check the definitions of CC, LIB, and LOCALFLAGS.
+
+LIB is the one most likely to give trouble.  The necessary libraries are likely to depend on the version of Unix you are using and on the configuration.  Library flags you might need include:
+| -lcrypt | Linux with SHADOW\_SUN option |
+|:--------|:------------------------------|
+| -lpam   | Any Unix with PAM option |
+| -ldl    | Linux with PAM (needed for dynamic loading of PAM modules |
+
+## 3. Compile ##
+
+The "make" command will compile the program.
+
+There should be no error messages.
+
+If there are error messages about undefined functions, then you may need to add some more libraries to the LIB definition in the Makefile.
+
+If you are compiling a PAM version and get error messages about not being able to find header files like "pam\_appl.h" then you may need to load some PAM development module that isn't part of the standard installation.
+
+## 4. PAM Configuration ##
+
+Skip this section if you are not using PAM.
+
+Every program that uses PAM needs a PAM configuration.  There are two common ways in which PAM configurations are arranged.
+
+If you have a /etc/pam.d directory, then you will need to create a file named "pwauth" inside it.  The exact commands needed vary among different Unix and Linux distributions.  Looking at the other files in that directory can give you a lot of clues about what is needed.  There are a few really old examples listed here. For more, see the [InstallNotes](InstallNotes.md) page.
+
+Under Redhat 6.x, I used this to authenticate out of the shadow password file:
+<pre>
+auth       required     /lib/security/pam_pwdb.so shadow nullok<br>
+auth       required     /lib/security/pam_nologin.so<br>
+account    required     /lib/security/pam_pwdb.so</pre>
+Under OS X 10.4.11, something like the following works (possibly the pam\_securityserver line should be removed):
+<pre>
+auth       required     pam_nologin.so<br>
+auth       sufficient   pam_securityserver.so<br>
+auth       sufficient   pam_unix.so<br>
+auth       required     pam_deny.so<br>
+account    required     pam_permit.so</pre>
+
+If you have a /etc/pam.conf file instead of a /etc/pam.d directory, then you need to
+add appropriate lines to that file.  For Solaris 2.6, you need to add lines like this to authenticate out of the shadow password file:
+<pre>
+pwauth  auth     required  /lib/security/pam_unix.so<br>
+pwauth  account  required  /lib/security/pam_unix.so</pre>
+To authentication from an SMB server on Solaris 2.6, a line like this would be used:
+<pre>
+pwauth  auth    required  /lib/security/pam_smb_auth.so.1</pre>
+You may want a "nolocal" flag on that line if you are authenticating from a remote server, or you may not.  Note that if you configure pam\_smb so that root access isn't required, you should be able to use mod\_auth\_pam instead of mod\_auth\_external and pwauth and get faster authentications.
+
+## 5. Test Pwauth ##
+
+The simplest test is to start a root shell and just run pwauth.  It will attempt to read the login and password from standard input, so type a login name, hit return, then type a password, and hit return (the password will echo on your screen).  The check the status code that was returned (in csh: "echo $status"  in sh: "echo $?").
+
+If the login/password were correct you should get a zero status code.  If not, you will get some other value.  See the list of [status codes](StatusCodes.md) to find the meaning of the various values returned.  Any values 50 or greater indicate a configuration error.
+
+## 6. Install Pwauth ##
+
+Install it in some sensible place (say, /usr/local/libexec/pwauth).  Unless you are doing SHADOW\_NONE, it should be installed suid-root so that it has the necessary access to read the password database.  That is:
+<pre>
+chown root pwauth<br>
+chmod u+s pwauth</pre>
+
+If you are using the group method of regulating access to pwauth, then you should chgrp the installed file to whatever group you are using, and permit the file so the only the group can run it ("chmod 4710 pwauth").
+
+You should probably do a final test, by su-ing to whatever user will be running pwauth (e.g. "httpd") and running it from that account.
+
+## 7. Configure the Calling Program ##
+
+You will probably need to do some configuration of whatever program is supposed to be invoking pwauth.
+
+If that program is mod\_auth\_external or mod\_authnz\_external, then  [configuration instructions](InstallApache.md) are available here.
\ No newline at end of file
diff --git a/InstallNotes.md b/InstallNotes.md
new file mode 100644 (file)
index 0000000..f7891d7
--- /dev/null
@@ -0,0 +1,27 @@
+# Introduction #
+
+This page includes notes on installing pwauth on various versions of Unix. These notes are mostly user contributed. If you have information to add, feel free to edit this page.
+
+# OS X #
+
+## OS X - Version 10.6.6 ##
+
+From Micah R Ledbetter:
+
+  * Use the regular PAM option not the PAM\_OS\_X or PAM\_OLD\_OS\_X option. Those apply only to versions 10.5 and before.
+
+  * The Mac OS X apache user id uid 70.
+
+  * I copied the contents of the pre-existing /etc/pam.d/sshd file into /etc/pam.d/pwauth, and it worked just fine.
+```
+      auth       optional       pam_krb5.so
+      auth       optional       pam_mount.so
+      auth       sufficient     pam_serialnumber.so serverinstall legacy
+      auth       required       pam_opendirectory.so
+      account    required       pam_nologin.so
+      account    required       pam_sacl.so sacl_service=ssh
+      account    required       pam_opendirectory.so
+      password   required       pam_opendirectory.so
+      session    required       pam_launchd.so
+      session    optional       pam_mount.so
+```
\ No newline at end of file
diff --git a/Introduction.md b/Introduction.md
new file mode 100644 (file)
index 0000000..7e3bc06
--- /dev/null
@@ -0,0 +1,73 @@
+# Introduction #
+
+**pwauth** is a unix authentication checking tool, designed to be run by other programs that need to know if a login/password combination is valid.  It was originally designed to do web authentications, in combination with [mod\_auth\_external or mod\_authnz\_external](http://code.google.com/p/mod-auth-external/), but has been used in many other web applications and in mail servers.
+
+What **pwauth** actually does is very simple.  You pass it a login and password, and it
+returns a flag telling if they are valid.  Normally it checks against your Unix server's system password database, but it can also be configured to use PAM to authentication from a wide range of other sources.
+
+# Why? #
+
+On unix systems, checking the validity of a password normally requires root access, and all that tools that normally do that ("su", "login", "passwd", etc) run as root.  Normally if you wanted to check web passwords against that database you'd have to somehow give the http daemon access to the password database.  This would be a horrible idea from a security point of view, however, because any bug in that large complex program, or any of the programs it runs (like user CGI scripts) could open a hole through which your entire password database could be compromised.
+
+**Pwauth** provides a way around that.  Instead of giving the http daemon access to the password database, you let it run **pwauth**, perhaps using mod\_auth\_external.  **Pwauth** is a much smaller program with a much narrower purpose, and is thus much easier to make secure.
+
+# Typical Applications #
+
+Typical applications for **pwauth** include:
+  * _Basic Authentication for Web Applications_.
+> "Basic Authentication" is the authentication system built into most browsers, where the browser provides a pop-up login box asking the user for their login/password and the authentication is negotiated between the user's browser and the http daemon. This is relatively rarely used on production websites these days. In this configuration pwauth is run by Apache through the mod\_auth\_external. It can be used to protect both CGI programs and static documents. CGIs do not have to do any authentication themselves - the name of the logged in users, if any, is passed to them by Apache.
+
+  * _Form-Based Authentication for Web Applications_.
+> In most modern websites authentication is not handled by the http daemon, but by the CGI programs running under it. In such cases, the login/password input boxes generally appear on the web page, and the data is passed to the CGI program, which does the check against the user database itself. Usually after the inital login the CGI program issues a session ID which is then sent back to the server with each new page request, so that we can tell that the user is already logged in. In this configuration, **pwauth** would be run directly by the CGI. Mod\_auth\_external is not needed.
+
+  * _SMTP Authentication for Mail Servers_.
+> The **pwauth** program has been used with the exim mail server to authenticate users.  See instructions [here](http://wiki.exim.org/AuthenticatedSmtpUsingPwauth).
+
+  * _Many Others_
+> Any time a non-root program wants to check the validity of an authentication, **pwauth** is likely to be a useful tool, so it has been used in a wide variety of applications, including [Hudson](http://wiki.hudson-ci.org/display/HUDSON/pwauth) and [MediaWiki](http://www.mediawiki.org/wiki/Extension:PwAuthPlugin).
+
+# Authentication Sources #
+
+**Pwauth** can check logins any of a variety of unix password database API's:
+
+  * _Direct system password database access_.
+> This uses the low-level system interface to the password database to check the password. Typically this means calling something like getpwnam() to look the given login name up the database, and then running crypt() on the given password to see if it matches the value in the database. The exact system calls vary significantly for different unix systems. Pwauth includes support for all popular systems and some unpopular ones. This is generally the best approach from a pure performance point of view.
+
+  * _PAM authentication_.
+> PAM (Portable Authentication Module) is a still higher level interface to the authentication system supported by some versions of Unix (notably Solaris, Linux and FreeBSD). With PAM there is a configuration file that specifies the authentication requirements for different programs, designating which dynamically loaded libraries to use to do the authentication. Authentication from the system password database is only one of many possibilities. Another common application is to use the pam\_smb module to do NT-style SMB authentication.
+
+  * _Login.conf authentication_. (currently OpenBSD only)
+> Some versions of Unix, mainly the BSD versions, have a "login.conf" file that can be used to configure authentication for different classes of users. Among other things, the configuration file specifies a program to be run to authenticate a user. For OpenBSD only, version 2.3.0 of pwauth adds the ability to read the login.conf file and authenticate users by the method specified there. Though substantially slower than directly accessing the password database, this configuration is useful if you are using unusual settings in "login.conf" and want pwauth to comply with them.
+
+  * _AIX authentication_.
+> The AIX operating system has it's own mechanism, similar to login.conf, that can be used to configure authentication for each user. Version 2.3.9 of pwauth adds the ability to authenticate through this interface.
+
+# Features #
+
+Other configurable features of pwauth include:
+
+  * _Lastlog support_. Many Unix systems maintain a lastlog file that keeps record of the last login on each account. Pwauth can be configured to update this on each successful authentication.
+
+  * _Restrictions on calling process uid_. Pwauth can be configured to only work for uids on a short list. Normally this would include only the uid that the HTTP daemon runs on. It will decline to run for any other users. This would mostly prevent users logged into the system from running the program directly - not that it would give them any information that the 'su' or 'passwd' programs wouldn't give them, but it is easier to interface a password guessing program to pwauth than to those, so restricting who can run it is useful.
+
+  * _Restrictions on authentiated uids_. Pwauth is normally configured to reject all attempts to log into accounts with uids below some value. This prevents it's use on system accounts.
+
+  * _Understand expired logins and passwords_. Most versions of Unix today include mechanisms where by login IDs can be set to expire after a certain date. There are also mechanisms by which passwords can be made to expire, so that the account becomes inaccessible if the password is not changed by that date. Pwauth version 2.3.0 is configured by default refuse all attempts to log into accounts that have expired logins or passwords. Of course, since it cannot send messages to the user, it cannot warn of impending expirations. This would have to be done by your CGIs.
+
+  * _Understand /etc/nologin_. On most Unix systems, if you create a file named /etc/nologin then users will not be able to log in. The contents of the file are displayed to them instead. Pwauth version 2.3.0 is configured by default to refuse logins if that file exists, though it cannot, of course, display the contents. You can also configure it to use a different file, so that pwauth authentications can be disabled separately from regular logins.
+
+  * _Sequentialized sleep after bad logins_. Normally you don't want authentication programs to be too fast, because that would allow people to zip through a dictionary of password guesses very quickly. Traditional Unix login programs sleep a bit before giving you a chance to try another password after one has failed. This is more complex to do with HTTP authentication because the user doesn't need to wait for the response of the first one to make another request - the same user can easily run many requests at the same time. In the default configuration, pwauth gets an exclusive lock on a file after every authentication request. On successful authentications, it drops the lock immediately, but on unsuccessful authentications it sleeps a few seconds before dropping it. Under normal usage, this should have no noticable effect, but after a failed authentication attempt, all pwauth processes on the system will be held up for a couple seconds. So even if a user tries barraging your system with password guesses, he will get responses back no faster than one every couple seconds. In the meantime, valid authentications could get very slow, and the system will accumulate a large number of processes blocked on the lock file. Admittedly not ideal. Maybe if I ever see this happen, I'll implement some better behavior for that case.
+
+  * _Failure logs_. Basically, a failure log keeps count of how many consecutive bad logins are made, and on the next good login, reports the failure count, and resets it to zero. It may also disable login attempts if some limit is exceeded. Relatively few unix login programs do this, but, starting with version 2.3.0, pwauth can support this even if the regular login system does not. At least, it does the part about incrementing the count on bad logins and disabling accounts that exceed some limit. However there is no path by which the pwauth could report the bad login count to the user. If you want to report failed logins, the pwauth distribution includes a checkfaillog utility that can be run from a CGI after a successful login to report the failed logins and reset the count to zero.
+
+  * _Suppression of core dumps_. On some versions of Unix core dump files can be publically readable. Since a core dump from pwauth would likely include a user's plain text password and possibly fragments of the system password file, this is undesirable. Pwauth disables core dumps.
+
+Because in typical configurations pwauth is run very frequently (on each HTTP request to a protected page), all configuration is compiled in. This means it does not have to read and parse a configuration file on every run, improving performance. It does mean that you need to recompile pwauth every time you change it's configuration. (But, of course, it does not have to be recompiled if the PAM or login.conf configuration is changed.)
+
+# Security Considerations #
+
+I believe that pwauth, with mod\_auth\_external, is the most secure method for doing web authentication out of unix shadow password systems. Mod\_auth\_pam or mod\_auth\_system can also do this, but since they are internal authenticators, they will only work if you make the shadow password file readable to the http server. This means that if there are any exploitable vulnerabilities in the http server, then it may be possible for people to grab a copy of your shadow password file. Worse, any CGI program on your system which is not run under suExec or cgiwrap also has read access to your shadow password database, and any bugs in these might also expose your entire password database. When mod\_auth\_external and pwauth are used, neither the http server nor any CGI programs are given access to the shadow database. Only the pwauth program does. Since it is a small and simple program, it is much easier to assure that it does not have security weaknesses.
+
+Having said that, web authentication from a Unix password file is an idea that many sensible people find [seriously questionable](Risks.md). We developed it for use on a system whose security concerns are [very unusual](http://www.cyberspace.org/staffnote/goals.html), and it has worked well for us over many years, in the face of fairly intense hacker activity.  Pwauth has features that can address mitigate many of the risks if correctly configured, but you need to be aware of the issues and extremely careful.
+
+A fundamental security problem with web authentication is that the passwords are sent in clear text over the network. In the case of basic authentication, they are sent with every page request. Furthermore, with the http protocol, unlike a protocol like telnet, copies of passwords are likely to be cached in various places along the way. Though exploits based on this are rare, it is a fundamentally sloppy way to treat a password. I strongly recommend that pwauth be used with the https protocol, which encrypts all requests including the passwords, whenever possible.
\ No newline at end of file
diff --git a/ProjectHome.md b/ProjectHome.md
new file mode 100644 (file)
index 0000000..564c57f
--- /dev/null
@@ -0,0 +1,10 @@
+# pwauth #
+**Author and maintainer**: [Jan Wolter](http://unixpapa.com/) ([email](http://unixpapa.com/white.cgi))
+
+**Pwauth** is an authenticator designed to be used with [mod\_auth\_external or mod\_authnz\_external](http://code.google.com/p/mod-auth-external/) and the Apache HTTP daemon to support reasonably secure web authentication out of the system password database on most versions of Unix.
+
+What pwauth actually does is very simple: given a login and a password, it returns a status code indicating whether it is a valid login/password or not. It is normally installed as an suid-root program, so other programs (like Apache or a CGI program) can run it to check if a login/password is valid even though they don't themselves have read access to the system password database.
+
+Though originally designed for web authentication, it can be used for other authentication applications, such as with the [exim](http://wiki.exim.org/AuthenticatedSmtpUsingPwauth) mail server.
+
+People considering use of pwauth should be aware that there are innate security risks when you allow system passwords to be used on the web.  Please be sure to read the wiki page on [security risks](Risks.md).
\ No newline at end of file
diff --git a/Risks.md b/Risks.md
new file mode 100644 (file)
index 0000000..7351d92
--- /dev/null
+++ b/Risks.md
@@ -0,0 +1,51 @@
+## Security Risks ##
+
+I believe that pwauth, if properly used, provides the most secure method of doing web authentication with system passwords.  However, many knowledgeable people would say that this is equivalent to talking about the safest way to shoot yourself in the head.  Using system accounts for web access can be an extremely bad idea.  You should understand why this is and think carefully about the risks before deciding if you want to do this.
+
+System accounts are typically much more useful and powerful than the ordinary user accounts in web applications.  They can normally be used to log into the server and start an interactive command shell from which many system resources can be accessed and modified.  Since those users have access to hundreds of programs on your system, there is a good chance that they will be able to find a security hole in one of them that will let them escalate themselves to superuser on your server, at which point they own your server and all the data on it, including, with a little work, all your user's passwords.  System accounts are very high value accounts, and should be accorded extra protection.
+
+These days most systems only allow system account logins via the SSH protocol, which is a very sophisticated protocol designed from the ground up for security.  The old TELNET and non-anonymous FTP protocols are rarely used anymore because they provide much less secure communications, with greater risk of a system account being compromised.  However, either one of those old abandoned protocols is far more secure than HTTP.  Here are a few of the weaknesses of HTTP:
+
+  * **Promiscuous transmission of plain-text passwords.**  The old TELNET protocol used to send your plain-text password over the net just once, when you were logging in.  HTTP's basic authentication protocol sends it in plain-text in the header of every single request you make.
+
+  * **Caching on intermediate servers.**  In the TELNET protocol, connections were direct from the user's computer to the server.  HTTP allows intermediate proxy servers to cache requests and the passwords with them, so your password may end up stored on all sorts of mysterious computers.
+
+  * **Server Impersonation.**  The SSH protocol has elaborate checks built into it that try to ensure that you are giving your password to the real server and not an impostor.  HTTP has no such checks.  It is certainly possible to fool the user, and maybe possible to fool the browser into giving away passwords to fake servers.
+
+  * **No speed limits on password guessing.**  If you enter a wrong password at a standard login prompt, there is typically a delay before you can try another.  The connection may be dropped after a few wrong guesses.  All this slows down programs that try using dictionary attacks to guess passwords.  In HTTP there are no such limitations.  You can send thousands of HTTP requests every second and keep doing it as long as you like.
+
+  * **Difficulty of Monitoring.**  It's harder to notice password guessing or unauthorized accesses when they happen over the web, unless you are really alert in monitoring web access logs and error logs.
+
+  * **Browser password caching.**  Most browsers practically beg you to let them remember your password for them.  No doubt some of your users will do this, and it is obviously possible for any virus or malicious user who gains access to their computer to extract those remembered passwords.  If one program (the browser) can get them, then other programs can be written to do the same thing.
+
+  * **Browser vulnerabilities.**  Most TELNET clients were simple programs, fairly unbuggy and hard to exploit.  HTTP clients, on the other hand, are nightmarishly complex and notoriously riddled with security flaws.  Are you sure that nifty new plugin you installed last night doesn't quietly send copies of every password you enter to Nigeria?
+
+  * **Lack of idle timeouts.**  If you wandered away from your computer, your TELNET connection would probably timeout after a while disconnecting you.  A basic authentication login _NEVER_ times out.  You can't even log out of it on most browsers except by completely exiting the browser.  Closing the window does not log you out.  Even closing all browser windows will not log you out on a Macintosh.  The risk of leaving active sessions laying around for other users who come to the computer later is high.
+
+So, if this is such a bad idea, why did I ever write pwauth?  Well, the server I wrote it for, and the only one I ever used it on, was [Grex](http://cyberspace.org), an old public access Unix system which gives away free Unix shell accounts to anyone who asks for one.  On a server where system accounts are routinely given away to strangers, the whole security risk equation is obviously very different.
+
+Of course, many of the concerns listed above can be mitigated by features built into pwauth, or by careful configuration and administration of the server.  You may have your own reasons why you are less concerned about the risks.  For example, I might be more comfortable using pwauth on an intranet than on the open net.  But you really should consider whether you should let your users have separate accounts for web access, with different logins and passwords, so that the consequences of one being compromised are not so great.
+
+It should also be noted that in some cases these risks may be difficult to avoid.  If you have a set of users who access your server both via the web and via ssh, then you could have separate login/password databases for the different kinds of access, thus avoiding exposing system passwords on the web, but your users are very likely to undo your good work by choosing the same passwords in both databases, and grow more reluctant to change them periodically because of the annoyance of having to change them in two places.  (Though, come to think of it, you could have the password setting program from your web app, run pwauth to check that the password the user is setting for his web password does NOT match his system password.)
+
+## Mitigating Risks ##
+
+How can we counteract the risks described above?  Well, some are hard, and some are easy.
+
+  * **Use HTTPS.**  Clearly requiring the secure https protocol for all authenticated transactions will help with many of these problem.  Passwords will still be sent in every query, but not in clear text.  Caching by proxies ceases to be a problem, and the risks of impostor servers are somewhat reduced.
+
+  * **Serialized Sleep on Bad Logins.**  When an authentication fails with pwauth, it will grab an exclusive lock on a file and then sleep for a few seconds.  This causes all pwauth authentications on the server to be held up a bit, slowing things down for password guessers.  So instead of successfully guessing a password, an aggressive password guesser will probably just lock up your server.  Not ideal, but an improvement.  This can be disabled, but it is probably a bad idea to do so.
+
+  * **Failure Logging.**  Pwauth can be configured to count the number of failed login attempts to each account since the last successful one, and to refuse further login attempts if the number goes too high. This is another way to limit password guessing.
+
+  * **Don't Use Mod\_Authn\_Socache.** This module, new in Apache 2.4, is very tempting. It caches login credentials so that you don't have to keep re-running the authenticator over and over again for the same user. That's a big performance gain. But the cache it maintains is essentially an Apache-readable copy of your system password file, containing the encrypted passwords of your active users. Having that sitting around is only slightly less of a problem than making your password file readable to Apache would have been in the first place.
+
+  * **Monitoring Logs.**  Many attacks against pwauth could be noticed early if you monitor the logs carefully, including the access logs, error logs and failure logs.  Ideally you would have tools in place that automatically detect attacks in progress so that defensive action can be taken quickly.
+
+  * **Form-based Authentication.**  With basic authentication users cannot log off easily and there are no idle timeouts.  Using a [form-based authentication](FormAuth.md) approach can solve these problems, if done carefully.
+
+All of these can help, but you shouldn't imagine that they completely solve the problem, and most of them increase the difficulty of setting up and maintaining the system.
+
+On the other hand, since I wrote the first version of pwauth in 1996, I have never heard of a single incident in which someone successfully exploited it.  Probably that's because people have had the good sense not to use it on high-value servers that attract concerted attacks by skilled hackers.
+
+So use your own judgement.  It's a useful tool, but not for every application.
\ No newline at end of file
diff --git a/StatusCodes.md b/StatusCodes.md
new file mode 100644 (file)
index 0000000..3fb156d
--- /dev/null
@@ -0,0 +1,21 @@
+# Status Codes #
+
+[Pwauth](Introduction.md) will always exit with one of the status codes listed in the table below.
+
+Codes 50 and above usually represent configuration errors in pwauth.
+| **code** | **internal name** | **description** |
+|:---------|:------------------|:----------------|
+|  0  | STATUS\_OK | Login OK. |
+|  1  | STATUS\_UNKNOWN | Nonexistant login or (for some configurations) incorrect password. |
+|  2  | STATUS\_INVALID | Incorrect password (for some configurations).  |
+|  3  | STATUS\_BLOCKED | Uid number is below MIN\_UNIX\_UID value configured in config.h. |
+|  4  | STATUS\_EXPIRED | Login ID has expired. |
+|  5  | STATUS\_PW\_EXPIRED | Login's password has expired. |
+|  6  | STATUS\_NOLOGIN | Logins to system have been turned off (usually by /etc/nologin file). |
+|  7  | STATUS\_MANYFAILES | Limit on number of bad logins exceeded. |
+| 50  | STATUS\_INT\_USER | pwauth was invoked by a uid not on the SERVER\_UIDS list.  If you get this error code, you probably have SERVER\_UIDS set incorrectly in pwauth's config.h file. |
+|  51 | STATUS\_INT\_ARGS | pwauth was not given a login & password to check.  The means the passing of data from mod\_auth\_external to pwauth is messed up.  Most likely one is trying to pass data via environment variables, while the other is trying to pass data via a pipe. |
+|  52 | STATUS\_INT\_ERR | one of several rare and unlikely internal errors occurred.  You'll have to read the source code to figure these out. |
+|  53 | STATUS\_INT\_NOROOT | pwauth was not able to read the password database.  Usually this means it is not running as root.  (PAM and login.conf configurations will return 1 in this case.) |
+
+If you see a negative error code (or a number like 255 or 254) reported in the Apache error log, then that is an error code from `mod_authnz_external` and means that it was unable to run pwauth at all.  See the [mod\_auth\_external documentation](http://code.google.com/p/mod-auth-external/wiki/Configuration) for more information.
\ No newline at end of file
diff --git a/TableOfContents.md b/TableOfContents.md
new file mode 100644 (file)
index 0000000..e69de29