Bug 53692 - mod_auth_form loses request body before login page can be created
Summary: mod_auth_form loses request body before login page can be created
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_auth_form (show other bugs)
Version: 2.4.2
Hardware: Other Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-08-10 21:43 UTC by bannis
Modified: 2013-05-21 17:58 UTC (History)
0 users



Attachments
httpd conf file for test case, put in /etc/httpd/conf.d or equiv. (806 bytes, text/plain)
2013-05-17 14:55 UTC, David Mansfield
Details
start page for test case. put in /var/www/form_auth_test (273 bytes, text/html)
2013-05-17 14:55 UTC, David Mansfield
Details
login form generator - can't see POST data. put in /var/www/form_auth_test_cgi (216 bytes, text/plain)
2013-05-17 14:56 UTC, David Mansfield
Details
alternative login handler using mod_include. put in /var/www/form_auth_test (47 bytes, text/plain)
2013-05-17 14:56 UTC, David Mansfield
Details
a hack which makes it work (1.64 KB, patch)
2013-05-21 17:58 UTC, David Mansfield
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description bannis 2012-08-10 21:43:03 UTC
Module mod_auth_form is losing POSTed data with default encoding before it can be made part of a login form. This does not happen with multipart/form encoding. The KEEP_BODY input filter is in place. Some simple debugging suggests that the issue is with the module's call to ap_parse_form_data. Whatever that function is doing with the data it reads as part of the subrequest, it's not making it back to the main input stream.
Comment 1 David Mansfield 2013-05-02 17:41:22 UTC
This is currently biting me. The whole point of "Inline Login with Body Preservation" is impossible unless the original POST data can be seen by the login page.
Comment 2 David Mansfield 2013-05-17 14:48:13 UTC
In contrary to the findings in the original entry, I have found the POST data is lost irrespective of the form encoding.

I have created a test case which I will attach.


formauth.conf => place in /etc/httpd/conf.d or equiv
start.html => place in /var/www/form_auth_test as per conf
login.shtml => ditto (to activate this change the ErrorDocument in conf)
login.cgi => place in /var/www/form_auth_test_cgi as per conf 

Here are some comments regarding the test case:

In this example I will show that by the time the ErrorDocument for 401 is invoked (which is the way "inline authentication with body preservation" works), that the POST body has been discarded and the request has been converted from POST to GET (these are probably related).

So in this example there is a page /start.html which is NOT within the "private" area of the site.  It has a simple form which gets POSTed to /private/target.html (which doesn't need to exist because we fail before it's relevant).

The authentication hook intercepts the POST, and the mod_auth_form throws a 401, which is handled with the ErrorDocument 401 /cgi-bin/login.cgi (or /login.shtml)

When login.cgi runs there is no POST data on STDIN and REQUEST_METHOD is always GET.

BTW, I have also tried using ErrorDocument 401 /login.shtml (via mod_include) but the result is the same.
Comment 3 David Mansfield 2013-05-17 14:55:13 UTC
Created attachment 30295 [details]
httpd conf file for test case, put in /etc/httpd/conf.d or equiv.
Comment 4 David Mansfield 2013-05-17 14:55:44 UTC
Created attachment 30296 [details]
start page for test case. put in /var/www/form_auth_test
Comment 5 David Mansfield 2013-05-17 14:56:03 UTC
Created attachment 30297 [details]
login form generator - can't see POST data. put in /var/www/form_auth_test_cgi
Comment 6 David Mansfield 2013-05-17 14:56:26 UTC
Created attachment 30298 [details]
alternative login handler using mod_include. put in /var/www/form_auth_test
Comment 7 bannis 2013-05-17 22:08:44 UTC
There may be more than one point of failure. A quick patch to mod_auth_form to pass the kept body from the body-parsing subrequest to the current request was enough to let a custom module find the body for drawing a login page, but a cgi still didn't see it. I don't know if it's related, but if you put a hard-coded body into the login page, mod_auth_form sees it, but it doesn't make it to the destination cgi
Comment 8 David Mansfield 2013-05-20 16:03:13 UTC
I have debugged this as well and found that the ErrorDocument 401 handler will ultimately end up calling "internal_internal_redirect" where a new request_rec is created for the 401 handler, and the kept_body is not passed to it. I.e it MAY need:

  new->kept_body = r->kept_body;  // on-or-around line 488 of http_request.c

Having "fixed" this and gone back into the debugger, I found that the kept_body filter ignores r->kept_body unless ap_filter_t::ctx  variable is initialized properly, and the filters on the original request and on the request created in internal_internal_redirect are not the same "instances" so we have f->ctx is null in the subrequest.

This is where my ability to debug ended.
Comment 9 David Mansfield 2013-05-20 16:06:21 UTC
Oh and of course, you are right (comment#7) that the mod_auth_form is ALSO missing:
  
  r->kept_body = rr->kept_body; // on-or-around line 1016 of mod_auth_form.c

That is a prerequisite to dropping the kept_body in internal_internal_redirect.
Comment 10 David Mansfield 2013-05-21 17:58:38 UTC
Created attachment 30306 [details]
a hack which makes it work

The attached patch makes this work for me with a CGI ErrorDocument, but still doesn't work with mod_include ErrorDocument. 

I cannot vouch for the overall correctness of this.