Bug 59626 - mod_ssl configuration directives ExportCertData and StdEnvVars, and other ssl environment variables can't be used with a fastcgi authenticator
Summary: mod_ssl configuration directives ExportCertData and StdEnvVars, and other ssl...
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_ssl (show other bugs)
Version: 2.5-HEAD
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-24 13:24 UTC by Guilherme Destefani
Modified: 2016-05-24 13:34 UTC (History)
0 users



Attachments
Patch that moves variables export to access hook, and erases the now the empty fixup hook. (8.73 KB, patch)
2016-05-24 13:24 UTC, Guilherme Destefani
Details | Diff
Test program. See instructions inside the source. (1.97 KB, text/x-csrc)
2016-05-24 13:26 UTC, Guilherme Destefani
Details
Configuration file to test the bug. (2.24 KB, text/plain)
2016-05-24 13:27 UTC, Guilherme Destefani
Details
Certificate authority used to test mod_ssl. (1.34 KB, application/pkix-cert)
2016-05-24 13:28 UTC, Guilherme Destefani
Details
Certificate chain used to test mod_ssl and httpd. (2.76 KB, application/pkix-cert)
2016-05-24 13:29 UTC, Guilherme Destefani
Details
User certificate used to test mod_ssl and httpd (4.10 KB, application/x-pkcs12)
2016-05-24 13:30 UTC, Guilherme Destefani
Details
Private key used to test mod_ssl and httpd (1.66 KB, application/pkix-cert)
2016-05-24 13:31 UTC, Guilherme Destefani
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Guilherme Destefani 2016-05-24 13:24:34 UTC
Created attachment 33873 [details]
Patch that moves variables export to access hook, and erases the now the empty fixup hook.

The mod_ssl configuration directives ExportCertData and StdEnvVars can be used to export certificate information to fastcgi responders, but mod_ssl don't export those same variables to a fcgi authenticator (mod_authnz_fcgi).

Those variables are exported in the fixup handler, but the auth module need those variables in the checkuser_id/auth phase, and those hooks are triggered before the fixup phase.

See http://www.fmc-modeling.org/category/projects/apache/amp/3_3Extending_Apache.html#fig:_Apache:_request-processing_+_Module_callbacks_PN for a visual workflow of the request processing cycle if needed.

One possible solution is simply move the variable export to the access handler hook, but I don't have enough knowledge of the httpd server to anticipate possible side effects. It seems that the fixup hook runs every time even for sub-requests, but the access checker is not repeated for sub-requests. This could break things in some other combination of modules configuration.
Anyone has other ideas about how to solve this problem?

If the fixup is called in some other situation, maybe a new function to stuff those variables and test whether HTTPS=on to skip the stuffing if already done before, or the module fcgi_auth could spawn a sub-request to get those variables. Those alternatives seem more complex than just move the code, so the patch attached just move the variables to the access hook.

To reproduce the problem:

1. Checkout https://svn.apache.org/repos/asf/httpd/httpd/trunk@1745196 in a Linux machine
2. Download all the attachments to the checkout directory
3. Download and install apr to srclib/apr/
4. build the web server:
# ./configure --enable-ssl --with-ssl --enable-proxy --enable-proxy-fcgi --enable-authnz-fcgi --with-apr=srclib/apr/
# make
5. Run the server in foreground:
# mkdir logs;./httpd -DFOREGROUND -d $PWD -f fcgi_test.conf
6. On another terminal, build and run the test program (it is both an fcgi AUTHORIZER and a RESPONDER):
# gcc -std=gnu99 -lfcgi fcgi_test.c -o fcgi_test&&./fcgi_test :9000
Please note that all logs are output in the httpd terminal.

7. Open a brower window, go to settings, certificates, CA, and import ca.crt as a new ca trusted to identify websites
8. Go to your certificates, import the test client certificate (in pkcs#12 format, encrypted with the passkey 123456, file usercert_passwd_123456.p12
9. Open the URL https://[::1]:8443/ (this example needs a machine with ipv6 + ipv4 enabled)

On success, SSL_CLIENT_CERT is exported to the authenticator, it should authorize and print all fcgi environment variables.

On fail, it should deny with 500 INTERNAL SERVER ERROR.

10. It is supposed to fail, and a message "AUTH ERROR Variable SSL_CLIENT_CERT not found." should appear in the browser window,
in the log (httpd terminal) there should be some lines with 
[authnz_fcgi:warn] [pid 29537:tid 140392828790528] [client ::1:38203] AH02507: handle_response: Logged from fcgi://127.0.0.1:9000: 'FCGI_ROLE=AUTHORIZER, SSL_CLIENT_CERT=NULLs
[authnz_fcgi:debug] [pid 29537:tid 140392828790528] mod_authnz_fcgi.c(772): [client ::1:38203] AH02515: req_rsp: Received HTTP status 500, referer: https://[::1]:8443/

11. Apply the patch:
$ patch -p0 < Moving-the-export-of-ssl-variables-from-fixup-to-acc.patch 
patching file modules/ssl/mod_ssl.c
patching file modules/ssl/ssl_engine_kernel.c
patching file modules/ssl/ssl_private.h

12. Rebuild the webserver and run it again.
You should see a webpage with:
Variable FCGI_ROLE=RESPONDER
Variable HTTPS=on
Variable SSL_SERVER_S_DN_CN=TEST_SERVER
...cut...
Variable SSL_CLIENT_CERT=-----BEGIN CERTIFICATE-----
...cut...
-----END CERTIFICATE-----

An in the httpd terminal:
[authnz_fcgi:warn] [pid 30431:tid 140291639047936] [client ::1:38301] AH02507: handle_response: Logged from fcgi://127.0.0.1:9000: 'FCGI_ROLE=AUTHORIZER, SSL_CLIENT_CERT=-----BEGIN CERTIFICATE-----\nMII
[authnz_fcgi:debug] [pid 30431:tid 140291639047936] mod_authnz_fcgi.c(772): [client ::1:38301] AH02515: req_rsp: Received HTTP status 200

If this patch is the final solution, the log message could be something like this:

Move the export of ssl variables from fixup to access hook.

The fixup handler is called after the handlers check_authn and check_authz,
so before this patch it was impossible to use the environment variable
SSL_CLIENT_CERT exported from mod_ssl configuration directive
SSLOptions ExportCertData (and the parsed variables exported with
StdEnvVars) in a fastcgi AUTHORIZER to build a custom access checker.
Comment 1 Guilherme Destefani 2016-05-24 13:26:22 UTC
Created attachment 33874 [details]
Test program. See instructions inside the source.

Use this program to test if apache httpd works with an Fcgi Authenticator
that checks client certificates using the variable SSL_CLIENT_CERT
exported with the mod_ssl configuration directive "SSLOptions +ExportCertData"
Run it like this:
gcc -std=gnu99 -lfcgi fcgi_test.c -o fcgi_test&&./fcgi_test :9000
This is *not* an example of how to program properly.
It is an AUTHORIZER and a RESPONDER in the same program.
Authorization succeeds with 200 OK if the environment has SSL_CLIENT_CERT,
otherwise 500 INTERNAL SERVER ERROR. As RESPONDER, prints all environment.
Comment 2 Guilherme Destefani 2016-05-24 13:27:38 UTC
Created attachment 33875 [details]
Configuration file to test the bug.

Use it to test httpd server with the test program.
Comment 3 Guilherme Destefani 2016-05-24 13:28:50 UTC
Created attachment 33876 [details]
Certificate authority used to test mod_ssl.
Comment 4 Guilherme Destefani 2016-05-24 13:29:20 UTC
Created attachment 33877 [details]
Certificate chain used to test mod_ssl and httpd.
Comment 5 Guilherme Destefani 2016-05-24 13:30:01 UTC
Created attachment 33878 [details]
User certificate used to test mod_ssl and httpd
Comment 6 Guilherme Destefani 2016-05-24 13:31:07 UTC
Created attachment 33879 [details]
Private key used to test mod_ssl and httpd