2 ** _ __ ___ ___ __| | ___ ___| | mod_ssl
3 ** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org
11 /* ====================================================================
12 * The Apache Software License, Version 1.1
14 * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. The end-user documentation included with the redistribution,
30 * if any, must include the following acknowledgment:
31 * "This product includes software developed by the
32 * Apache Software Foundation (http://www.apache.org/)."
33 * Alternately, this acknowledgment may appear in the software itself,
34 * if and wherever such third-party acknowledgments normally appear.
36 * 4. The names "Apache" and "Apache Software Foundation" must
37 * not be used to endorse or promote products derived from this
38 * software without prior written permission. For written
39 * permission, please contact apache@apache.org.
41 * 5. Products derived from this software may not be called "Apache",
42 * nor may "Apache" appear in their name, without prior written
43 * permission of the Apache Software Foundation.
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * ====================================================================
59 /* ``MY HACK: This universe.
60 Just one little problem:
65 /* _________________________________________________________________
67 ** I/O Request Body Sucking and Re-Injection
68 ** _________________________________________________________________
71 #ifndef SSL_CONSERVATIVE
76 * 1. When the client sends a HTTP/HTTPS request, Apache's core code
77 * reads only the request line ("METHOD /path HTTP/x.y") and the
78 * attached MIME headers ("Foo: bar") up to the terminating line ("CR
79 * LF"). An attached request body (for instance the data of a POST
80 * method) is _NOT_ read. Instead it is read by mod_cgi's content
81 * handler and directly passed to the CGI script.
83 * 2. mod_ssl supports per-directory re-configuration of SSL parameters.
84 * This is implemented by performing an SSL renegotiation of the
85 * re-configured parameters after the request is read, but before the
86 * response is sent. In more detail: the renegotiation happens after the
87 * request line and MIME headers were read, but _before_ the attached
88 * request body is read. The reason simply is that in the HTTP protocol
89 * usually there is no acknowledgment step between the headers and the
90 * body (there is the 100-continue feature and the chunking facility
91 * only), so Apache has no API hook for this step.
93 * 3. the problem now occurs when the client sends a POST request for
94 * URL /foo via HTTPS the server and the server has SSL parameters
95 * re-configured on a per-URL basis for /foo. Then mod_ssl has to
96 * perform an SSL renegotiation after the request was read and before
97 * the response is sent. But the problem is the pending POST body data
98 * in the receive buffer of SSL (which Apache still has not read - it's
99 * pending until mod_cgi sucks it in). When mod_ssl now tries to perform
100 * the renegotiation the pending data leads to an I/O error.
104 * There are only two solutions: Either to simply state that POST
105 * requests to URLs with SSL re-configurations are not allowed, or to
106 * renegotiate really after the _complete_ request (i.e. including
107 * the POST body) was read. Obviously the latter would be preferred,
108 * but it cannot be done easily inside Apache, because as already
109 * mentioned, there is no API step between the body reading and the body
110 * processing. And even when we mod_ssl would hook directly into the
111 * loop of mod_cgi, we wouldn't solve the problem for other handlers, of
112 * course. So the only general solution is to suck in the pending data
113 * of the request body from the OpenSSL BIO into the Apache BUFF. Then
114 * the renegotiation can be done and after this step Apache can proceed
115 * processing the request as before.
117 * Solution Implementation:
119 * We cannot simply suck in the data via an SSL_read-based loop because of
120 * HTTP chunking. Instead we _have_ to use the Apache API for this step which
121 * is aware of HTTP chunking. So the trick is to suck in the pending request
122 * data via the Apache API (which uses Apache's BUFF code and in the
123 * background mod_ssl's I/O glue code) and re-inject it later into the Apache
124 * BUFF code again. This way the data flows twice through the Apache BUFF, of
125 * course. But this way the solution doesn't depend on any Apache specifics
126 * and is fully transparent to Apache modules.
129 struct ssl_io_suck_st {
137 /* prepare request_rec structure for input sucking */
138 static void ssl_io_suck_start(request_rec *r)
140 struct ssl_io_suck_st *ss;
142 ss = ap_ctx_get(r->ctx, "ssl::io::suck");
144 ss = ap_palloc(r->pool, sizeof(struct ssl_io_suck_st));
145 ap_ctx_set(r->ctx, "ssl::io::suck", ss);
147 ss->bufptr = ap_palloc(r->pool, ss->buflen);
149 ss->pendptr = ss->bufptr;
155 /* record a sucked input chunk */
156 static void ssl_io_suck_record(request_rec *r, char *buf, int len)
158 struct ssl_io_suck_st *ss;
160 if ((ss = ap_ctx_get(r->ctx, "ssl::io::suck")) == NULL)
162 if (((ss->bufptr + ss->buflen) - (ss->pendptr + ss->pendlen)) < len) {
163 /* "expand" buffer: actually we cannot really expand the buffer
164 here, because Apache's pool system doesn't support expanding chunks
165 of memory. Instead we have to either reuse processed data or
166 allocate a new chunk of memory in advance if we really need more
171 if (( (ss->pendptr - ss->bufptr)
172 + ((ss->bufptr + ss->buflen) - (ss->pendptr + ss->pendlen)) ) >= len) {
173 /* make memory available by reusing already processed data */
174 memmove(ss->bufptr, ss->pendptr, ss->pendlen);
175 ss->pendptr = ss->bufptr;
178 /* too bad, we have to allocate a new larger buffer */
179 newlen = (ss->buflen * 2) + len;
180 newptr = ap_palloc(r->pool, newlen);
183 memcpy(ss->bufptr, ss->pendptr, ss->pendlen);
184 ss->pendptr = ss->bufptr;
187 memcpy(ss->pendptr+ss->pendlen, buf, len);
192 /* finish request_rec after input sucking */
193 static void ssl_io_suck_end(request_rec *r)
195 struct ssl_io_suck_st *ss;
197 if ((ss = ap_ctx_get(r->ctx, "ssl::io::suck")) == NULL)
200 r->read_body = REQUEST_NO_BODY;
204 ap_bsetflag(r->connection->client, B_CHUNK, 0);
208 void ssl_io_suck(request_rec *r, SSL *ssl)
217 if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) == OK) {
218 if (ap_should_client_block(r)) {
220 /* read client request block through Apache API */
221 buflen = HUGE_STRING_LEN;
222 buf = ap_palloc(r->pool, buflen);
223 ap_hard_timeout("SSL I/O request body pre-sucking", r);
225 ssl_io_suck_start(r);
226 while ((len = ap_get_client_block(r, buf, buflen)) > 0) {
227 ssl_io_suck_record(r, buf, len);
233 /* suck trailing data (usually CR LF) which
234 is still in the Apache BUFF layer */
235 while (ap_bpeekc(r->connection->client) != EOF) {
236 c = ap_bgetc(r->connection->client);
237 ssl_io_suck_record(r, &c, 1);
241 ssl_log(r->server, SSL_LOG_TRACE,
242 "I/O: sucked %d bytes of input data from SSL/TLS I/O layer "
243 "for delayed injection into Apache I/O layer", sucked);
249 /* the SSL_read replacement routine which knows about the suck buffer */
250 static int ssl_io_suck_read(SSL *ssl, char *buf, int len)
253 struct ssl_io_suck_st *ss;
254 request_rec *r = NULL;
257 actx = (ap_ctx *)SSL_get_app_data2(ssl);
259 r = (request_rec *)ap_ctx_get(actx, "ssl::request_rec");
263 ss = ap_ctx_get(r->ctx, "ssl::io::suck");
265 if (ss->active && ss->pendlen > 0) {
266 /* ok, there is pre-sucked data */
267 len = (ss->pendlen > len ? len : ss->pendlen);
268 memcpy(buf, ss->pendptr, len);
271 ssl_log(r->server, SSL_LOG_TRACE,
272 "I/O: injecting %d bytes of pre-sucked data "
273 "into Apache I/O layer", len);
279 rv = SSL_read(ssl, buf, len);
283 /* override SSL_read in the following code... */
284 #define SSL_read ssl_io_suck_read
286 #endif /* !SSL_CONSERVATIVE */
288 /* _________________________________________________________________
291 ** _________________________________________________________________
295 #include <sys/types.h>
299 static int ssl_io_hook_read(BUFF *fb, char *buf, int len);
300 static int ssl_io_hook_write(BUFF *fb, char *buf, int len);
302 static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt);
305 static int ssl_io_hook_recvwithtimeout(BUFF *fb, char *buf, int len);
306 static int ssl_io_hook_sendwithtimeout(BUFF *fb, const char *buf, int len);
309 void ssl_io_register(void)
311 ap_hook_register("ap::buff::read", ssl_io_hook_read, AP_HOOK_NOCTX);
312 ap_hook_register("ap::buff::write", ssl_io_hook_write, AP_HOOK_NOCTX);
314 ap_hook_register("ap::buff::writev", ssl_io_hook_writev, AP_HOOK_NOCTX);
317 ap_hook_register("ap::buff::recvwithtimeout",
318 ssl_io_hook_recvwithtimeout, AP_HOOK_NOCTX);
319 ap_hook_register("ap::buff::sendwithtimeout",
320 ssl_io_hook_sendwithtimeout, AP_HOOK_NOCTX);
325 void ssl_io_unregister(void)
327 ap_hook_unregister("ap::buff::read", ssl_io_hook_read);
328 ap_hook_unregister("ap::buff::write", ssl_io_hook_write);
330 ap_hook_unregister("ap::buff::writev", ssl_io_hook_writev);
333 ap_hook_unregister("ap::buff::recvwithtimeout", ssl_io_hook_recvwithtimeout);
334 ap_hook_unregister("ap::buff::sendwithtimeout", ssl_io_hook_sendwithtimeout);
339 static int ssl_io_hook_read(BUFF *fb, char *buf, int len)
345 if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
346 rc = SSL_read(ssl, buf, len);
348 * Simulate an EINTR in case OpenSSL wants to read more.
349 * (This is usually the case when the client forces an SSL
350 * renegotation which is handled implicitly by OpenSSL.)
352 if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)
357 if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
358 c = (conn_rec *)SSL_get_app_data(ssl);
359 ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
360 "SSL error on reading data");
363 * read(2) returns only the generic error number -1
369 rc = read(fb->fd_in, buf, len);
373 static int ssl_io_hook_write(BUFF *fb, char *buf, int len)
379 if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
380 rc = SSL_write(ssl, buf, len);
382 * Simulate an EINTR in case OpenSSL wants to write more.
384 if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE)
389 if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
390 c = (conn_rec *)SSL_get_app_data(ssl);
391 ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
392 "SSL error on writing data");
395 * write(2) returns only the generic error number -1
401 rc = write(fb->fd, buf, len);
406 /* the prototype for our own SSL_writev() */
407 static int SSL_writev(SSL *, const struct iovec *, int);
409 static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt)
415 if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
416 rc = SSL_writev(ssl, iov, iovcnt);
418 * Simulate an EINTR in case OpenSSL wants to write more.
420 if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE)
425 if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
426 c = (conn_rec *)SSL_get_app_data(ssl);
427 ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
428 "SSL error on writing data");
431 * writev(2) returns only the generic error number -1
437 rc = writev(fb->fd, iov, iovcnt);
444 /* these two functions are exported from buff.c under WIN32 */
445 API_EXPORT(int) sendwithtimeout(int sock, const char *buf, int len, int flags);
446 API_EXPORT(int) recvwithtimeout(int sock, char *buf, int len, int flags);
448 /* and the prototypes for our SSL_xxx variants */
449 static int SSL_sendwithtimeout(BUFF *fb, const char *buf, int len);
450 static int SSL_recvwithtimeout(BUFF *fb, char *buf, int len);
452 static int ssl_io_hook_recvwithtimeout(BUFF *fb, char *buf, int len)
457 if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL)
458 rc = SSL_recvwithtimeout(fb, buf, len);
460 rc = recvwithtimeout(fb->fd, buf, len, 0);
464 static int ssl_io_hook_sendwithtimeout(BUFF *fb, const char *buf, int len)
469 if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL)
470 rc = SSL_sendwithtimeout(fb, buf, len);
472 rc = sendwithtimeout(fb->fd, buf, len, 0);
478 /* _________________________________________________________________
480 ** Special Functions for OpenSSL
481 ** _________________________________________________________________
486 static int SSL_sendwithtimeout(BUFF *fb, const char *buf, int len)
491 int err = WSAEWOULDBLOCK;
497 ssl = ap_ctx_get(fb->ctx, "ssl");
499 if (!(tv.tv_sec = ap_check_alarm()))
500 return (SSL_write(ssl, (char*)buf, len));
502 rv = ioctlsocket(sock, FIONBIO, &iostate);
505 err = WSAGetLastError();
508 rv = SSL_write(ssl, (char*)buf, len);
510 if (BIO_sock_should_retry(rv)) {
514 FD_SET((unsigned int)sock, &fdset);
516 rv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
517 if (rv == SOCKET_ERROR)
518 err = WSAGetLastError();
520 ioctlsocket(sock, FIONBIO, &iostate);
521 if(ap_check_alarm() < 0) {
522 WSASetLastError(EINTR); /* Simulate an alarm() */
523 return (SOCKET_ERROR);
527 rv = SSL_write(ssl, (char*)buf, len);
528 if (BIO_sock_should_retry(rv)) {
529 ap_log_error(APLOG_MARK,APLOG_DEBUG, NULL,
530 "select claimed we could write, "
531 "but in fact we couldn't. "
532 "This is a bug in Windows.");
540 ioctlsocket(sock, FIONBIO, &iostate);
541 if (rv == SOCKET_ERROR)
542 WSASetLastError(err);
546 static int SSL_recvwithtimeout(BUFF *fb, char *buf, int len)
551 int err = WSAEWOULDBLOCK;
553 int sock = fb->fd_in;
557 ssl = ap_ctx_get(fb->ctx, "ssl");
559 if (!(tv.tv_sec = ap_check_alarm()))
560 return (SSL_read(ssl, buf, len));
562 rv = ioctlsocket(sock, FIONBIO, &iostate);
565 rv = SSL_read(ssl, buf, len);
567 if (BIO_sock_should_retry(rv)) {
571 FD_SET((unsigned int)sock, &fdset);
573 rv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
574 if (rv == SOCKET_ERROR)
575 err = WSAGetLastError();
577 ioctlsocket(sock, FIONBIO, &iostate);
579 WSASetLastError(WSAEWOULDBLOCK);
580 return (SOCKET_ERROR);
583 rv = SSL_read(ssl, buf, len);
584 if (rv == SOCKET_ERROR) {
585 if (BIO_sock_should_retry(rv)) {
586 ap_log_error(APLOG_MARK,APLOG_DEBUG, NULL,
587 "select claimed we could read, "
588 "but in fact we couldn't. "
589 "This is a bug in Windows.");
594 err = WSAGetLastError();
601 ioctlsocket(sock, FIONBIO, &iostate);
602 if (rv == SOCKET_ERROR)
603 WSASetLastError(err);
610 * There is no SSL_writev() provided by OpenSSL. The reason is mainly because
611 * OpenSSL has to fragment the data itself again for the SSL record layer, so a
612 * writev() like interface makes not much sense. What we do is to emulate it
613 * to at least being able to use the write() like interface. But keep in mind
614 * that the network I/O performance is not write() like, of course.
617 static int SSL_writev(SSL *ssl, const struct iovec *iov, int iovcnt)
624 for (i = 0; i < iovcnt; i++) {
625 if ((n = SSL_write(ssl, iov[i].iov_base, iov[i].iov_len)) == -1) {
635 /* _________________________________________________________________
637 ** I/O Data Debugging
638 ** _________________________________________________________________
641 #define DUMP_WIDTH 16
643 static void ssl_io_data_dump(server_rec *srvr, const char *s, long len)
647 int i, j, rows, trunc;
651 for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
653 rows = (len / DUMP_WIDTH);
654 if ((rows * DUMP_WIDTH) < len)
656 ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
657 "+-------------------------------------------------------------------------+");
658 for(i = 0 ; i< rows; i++) {
659 ap_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH);
660 ap_cpystrn(buf, tmp, sizeof(buf));
661 for (j = 0; j < DUMP_WIDTH; j++) {
662 if (((i * DUMP_WIDTH) + j) >= len)
663 ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
665 ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
666 ap_snprintf(tmp, sizeof(tmp), "%02x%c", ch , j==7 ? '-' : ' ');
667 ap_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
670 ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
671 for (j = 0; j < DUMP_WIDTH; j++) {
672 if (((i * DUMP_WIDTH) + j) >= len)
673 ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
675 ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
676 ap_snprintf(tmp, sizeof(tmp), "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.');
677 ap_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
680 ap_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf));
681 ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "%s", buf);
684 ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
685 "| %04x - <SPACES/NULS>", len + trunc);
686 ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
687 "+-------------------------------------------------------------------------+");
691 long ssl_io_data_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long rc)
697 if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL)
699 if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
703 if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
704 || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
706 ssl_log(s, SSL_LOG_DEBUG,
707 "%s: %s %ld/%d bytes %s BIO#%08X [mem: %08lX] %s",
709 (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
710 rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"),
712 (argp != NULL ? "(BIO dump follows)" : "(Ops, no memory buffer?)"));
714 ssl_io_data_dump(s, argp, rc);
717 ssl_log(s, SSL_LOG_DEBUG,
718 "%s: I/O error, %d bytes expected to %s on BIO#%08X [mem: %08lX]",
719 SSL_LIBRARY_NAME, argi,
720 (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),