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.
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.
Created attachment 33875 [details] Configuration file to test the bug. Use it to test httpd server with the test program.
Created attachment 33876 [details] Certificate authority used to test mod_ssl.
Created attachment 33877 [details] Certificate chain used to test mod_ssl and httpd.
Created attachment 33878 [details] User certificate used to test mod_ssl and httpd
Created attachment 33879 [details] Private key used to test mod_ssl and httpd