|
|
26c8e2 |
# ./pullrev.sh 1870095 1870097
|
|
|
26c8e2 |
http://svn.apache.org/viewvc?view=revision&revision=1870095
|
|
|
26c8e2 |
http://svn.apache.org/viewvc?view=revision&revision=1870097
|
|
|
26c8e2 |
|
|
|
26c8e2 |
--- httpd-2.4.37/modules/ssl/ssl_engine_kernel.c
|
|
|
26c8e2 |
+++ httpd-2.4.37/modules/ssl/ssl_engine_kernel.c
|
|
|
26c8e2 |
@@ -114,6 +114,45 @@
|
|
|
26c8e2 |
return result;
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
|
|
|
26c8e2 |
+/* If a renegotiation is required for the location, and the request
|
|
|
26c8e2 |
+ * includes a message body (and the client has not requested a "100
|
|
|
26c8e2 |
+ * Continue" response), then the client will be streaming the request
|
|
|
26c8e2 |
+ * body over the wire already. In that case, it is not possible to
|
|
|
26c8e2 |
+ * stop and perform a new SSL handshake immediately; once the SSL
|
|
|
26c8e2 |
+ * library moves to the "accept" state, it will reject the SSL packets
|
|
|
26c8e2 |
+ * which the client is sending for the request body.
|
|
|
26c8e2 |
+ *
|
|
|
26c8e2 |
+ * To allow authentication to complete in the hook, the solution used
|
|
|
26c8e2 |
+ * here is to fill a (bounded) buffer with the request body, and then
|
|
|
26c8e2 |
+ * to reinject that request body later.
|
|
|
26c8e2 |
+ *
|
|
|
26c8e2 |
+ * This function is called to fill the renegotiation buffer for the
|
|
|
26c8e2 |
+ * location as required, or fail. Returns zero on success or HTTP_
|
|
|
26c8e2 |
+ * error code on failure.
|
|
|
26c8e2 |
+ */
|
|
|
26c8e2 |
+static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc)
|
|
|
26c8e2 |
+{
|
|
|
26c8e2 |
+ int rv;
|
|
|
26c8e2 |
+ apr_size_t rsize;
|
|
|
26c8e2 |
+
|
|
|
26c8e2 |
+ /* ### this is HTTP/1.1 specific, special case for protocol? */
|
|
|
26c8e2 |
+ if (r->expecting_100 || !ap_request_has_body(r)) {
|
|
|
26c8e2 |
+ return 0;
|
|
|
26c8e2 |
+ }
|
|
|
26c8e2 |
+
|
|
|
26c8e2 |
+ rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE : dc->nRenegBufferSize;
|
|
|
26c8e2 |
+ if (rsize > 0) {
|
|
|
26c8e2 |
+ /* Fill the I/O buffer with the request body if possible. */
|
|
|
26c8e2 |
+ rv = ssl_io_buffer_fill(r, rsize);
|
|
|
26c8e2 |
+ }
|
|
|
26c8e2 |
+ else {
|
|
|
26c8e2 |
+ /* If the reneg buffer size is set to zero, just fail. */
|
|
|
26c8e2 |
+ rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
|
|
|
26c8e2 |
+ }
|
|
|
26c8e2 |
+
|
|
|
26c8e2 |
+ return rv;
|
|
|
26c8e2 |
+}
|
|
|
26c8e2 |
+
|
|
|
26c8e2 |
#ifdef HAVE_TLSEXT
|
|
|
26c8e2 |
static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2)
|
|
|
26c8e2 |
{
|
|
|
26c8e2 |
@@ -814,41 +853,14 @@
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
|
|
|
26c8e2 |
- /* If a renegotiation is now required for this location, and the
|
|
|
26c8e2 |
- * request includes a message body (and the client has not
|
|
|
26c8e2 |
- * requested a "100 Continue" response), then the client will be
|
|
|
26c8e2 |
- * streaming the request body over the wire already. In that
|
|
|
26c8e2 |
- * case, it is not possible to stop and perform a new SSL
|
|
|
26c8e2 |
- * handshake immediately; once the SSL library moves to the
|
|
|
26c8e2 |
- * "accept" state, it will reject the SSL packets which the client
|
|
|
26c8e2 |
- * is sending for the request body.
|
|
|
26c8e2 |
- *
|
|
|
26c8e2 |
- * To allow authentication to complete in this auth hook, the
|
|
|
26c8e2 |
- * solution used here is to fill a (bounded) buffer with the
|
|
|
26c8e2 |
- * request body, and then to reinject that request body later.
|
|
|
26c8e2 |
- */
|
|
|
26c8e2 |
- if (renegotiate && !renegotiate_quick
|
|
|
26c8e2 |
- && !r->expecting_100
|
|
|
26c8e2 |
- && ap_request_has_body(r)) {
|
|
|
26c8e2 |
- int rv;
|
|
|
26c8e2 |
- apr_size_t rsize;
|
|
|
26c8e2 |
-
|
|
|
26c8e2 |
- rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE :
|
|
|
26c8e2 |
- dc->nRenegBufferSize;
|
|
|
26c8e2 |
- if (rsize > 0) {
|
|
|
26c8e2 |
- /* Fill the I/O buffer with the request body if possible. */
|
|
|
26c8e2 |
- rv = ssl_io_buffer_fill(r, rsize);
|
|
|
26c8e2 |
- }
|
|
|
26c8e2 |
- else {
|
|
|
26c8e2 |
- /* If the reneg buffer size is set to zero, just fail. */
|
|
|
26c8e2 |
- rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
|
|
|
26c8e2 |
- }
|
|
|
26c8e2 |
-
|
|
|
26c8e2 |
- if (rv) {
|
|
|
26c8e2 |
+ /* Fill reneg buffer if required. */
|
|
|
26c8e2 |
+ if (renegotiate && !renegotiate_quick) {
|
|
|
26c8e2 |
+ rc = fill_reneg_buffer(r, dc);
|
|
|
26c8e2 |
+ if (rc) {
|
|
|
26c8e2 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02257)
|
|
|
26c8e2 |
"could not buffer message body to allow "
|
|
|
26c8e2 |
"SSL renegotiation to proceed");
|
|
|
26c8e2 |
- return rv;
|
|
|
26c8e2 |
+ return rc;
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
|
|
|
26c8e2 |
@@ -1132,6 +1144,17 @@
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
}
|
|
|
26c8e2 |
|
|
|
26c8e2 |
+ /* Fill reneg buffer if required. */
|
|
|
26c8e2 |
+ if (change_vmode) {
|
|
|
26c8e2 |
+ rc = fill_reneg_buffer(r, dc);
|
|
|
26c8e2 |
+ if (rc) {
|
|
|
26c8e2 |
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10228)
|
|
|
26c8e2 |
+ "could not buffer message body to allow "
|
|
|
26c8e2 |
+ "TLS Post-Handshake Authentication to proceed");
|
|
|
26c8e2 |
+ return rc;
|
|
|
26c8e2 |
+ }
|
|
|
26c8e2 |
+ }
|
|
|
26c8e2 |
+
|
|
|
26c8e2 |
if (change_vmode) {
|
|
|
26c8e2 |
char peekbuf[1];
|
|
|
26c8e2 |
|