
The mod_ssl package currently provides the ability to perform authorization
using information provided by the client certificate, via the SSLRequire
directive. The SSLRequire directive can be associated with directory either
in the httpd.conf file, or via a .htaccess file.

The SSLRequire directive can allow or deny access based on information in
the request and in the client certificate, as in this example:

SSLRequire	( %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." )

We have extended the SSLRequire expressions to allow the result of an
external program execution to be used in a test, by adding a function
named "exec", analagous to the "file" function that is currently provided.

The exec function takes one or more arguments that may be numbers, strings,
%{...} variables or function invocations. The exec function concatenates
the arguments and executes them as a shell command using the Unix popen()
system call. The exec function returns the output of the command as a 
string, which may be used in an SSLRequire expression. For example, the 
following SSLRequire grants access only to users with a user account on 
the web server host:

    SSLRequire	( exec("egrep '^", %{SSL_CLIENT_S_DN_UID}, ":' /etc/passwd") != "" )

In order to use LDAP to control authorization, we can use the 'ldapsearch' 
command-line query tool to fetch information via LDAP. This allows great
flexibility in the use of LDAP. The example query below will verify that 
the client UID is defined in corp's corporate email database:

SSLRequire ( exec("ldapsearch -h mail.corp.com -b ou=email,dc=corp,dc=com \
	           uid=", %{SSL_CLIENT_S_DN_UID}) != "" )

To maintain security, the exec() function will not execute the command 
if a variables used in the command contains one of the following shell
special characters:
		 \n ; $ # & | ( ) < > ` ' "

This prevents an attacker from using a specially prepared client certificate
to execute an arbitrary command with the web server's privileges on the host 
system.

As implemented, the exec() function returns no more than 255 bytes of output 
from the executed command. 

