Bug 39370 - SSL session will be removed if the client is sending close_notify
SSL session will be removed if the client is sending close_notify
Status: NEW
Product: Apache httpd-2
Classification: Unclassified
Component: mod_ssl
2.0-HEAD
Other other
: P2 normal (vote)
: ---
Assigned To: Apache HTTPD Bugs Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2006-04-20 20:43 UTC by keilh
Modified: 2006-04-20 13:43 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description keilh 2006-04-20 20:43:30 UTC
If the client is closing the SSL connection correctly, i.e. sending
the close_notify alert message, the SSL session will be removed.
See the follwowing stack:

  dummy_worker(opaque = 0x16b170)
   worker_thread(thd = 0x16b170, dummy = 0x245d30)
   apr_pool_clear(pool = 0x24b428)
   run_cleanups(cref = 0x24b438)
   ssl_io_filter_cleanup(data = 0x24b9a8)
   SSL_free(s = 0x265fa0)
   ssl_clear_bad_session(s = 0x265fa0)
   SSL_CTX_remove_session(ctx = 0x23efe8, c = 0x24f560)
   remove_session_lock(ctx = 0x23efe8, c = 0x24f560, lck = 1)
   remove_session_cb(session_ctx = 0x23efe8, session = 0x24f560)

That situation is common pattern for most browser: If the server is 
sending a redirect with a large response body, the browser does not completly
read the body. 

How to reproduce:
The easiest way is a cgi script that is sending data, sleeping for
a while, sending data, etc. After seeing the first chunk in the browser,
press the stop button. 

Fix: 
diff with httpd/2.2.0 (the same for httpd/2.0.x)
Index: modules/ssl//ssl_engine_io.c
===================================================================
RCS file:
/opt/projects/CVSROOT/navajo/src/org/apache/httpd-2.2.X/modules/ssl/ssl_engine_io.c,v
retrieving revision 1.2
diff -c -r1.2 ssl_engine_io.c
*** modules/ssl//ssl_engine_io.c        2006/02/01 17:10:55     1.2
--- modules/ssl//ssl_engine_io.c        2006/04/20 18:35:18
***************
*** 1439,1444 ****
--- 1439,1452 ----
              status = ssl_filter_write(f, data, len);
              apr_bucket_delete(bucket);

+                       /* try to read the  close_notify of the client*/
+                       if( APR_STATUS_IS_ECONNRESET(status ) &&
+                               SSL_peek(filter_ctx->pssl, NULL,0) == 0 &&
+                               SSL_get_shutdown(filter_ctx->pssl) ==
SSL_RECEIVED_SHUTDOWN
+                       ) {
+                               SSL_set_shutdown(filter_ctx->pssl,
(SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN));
+                       }
+
              if (status != APR_SUCCESS) {
                  break;
              }


Remarks:
in ssl_io_filter_output will be checked that
a) the connection has been closed 
b) the client has sent the close_notify alert
  (otherwise an attacker could drop the connection, i.e.
  a truncating attack. )

(a) is just for performance)