]> granicus.if.org Git - apache/blob - modules/ssl/ssl_engine_io.c
de-hungarian-ize server config member names which are going to stay
[apache] / modules / ssl / ssl_engine_io.c
1 /*                      _             _
2 **  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
3 ** | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| |   \__ \__ \ |  www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_|  ftp.modssl.org
6 **                      |_____|
7 **  ssl_engine_io.c
8 **  I/O Functions
9 */
10
11 /* ====================================================================
12  * The Apache Software License, Version 1.1
13  *
14  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
15  * reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * 1. Redistributions of source code must retain the above copyright
22  *    notice, this list of conditions and the following disclaimer.
23  *
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
27  *    distribution.
28  *
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.
35  *
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.
40  *
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.
44  *
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
56  * SUCH DAMAGE.
57  * ====================================================================
58  */
59                              /* ``MY HACK: This universe.
60                                   Just one little problem:
61                                   core keeps dumping.''
62                                             -- Unknown    */
63 #include "mod_ssl.h"
64
65 /*  _________________________________________________________________
66 **
67 **  I/O Hooks
68 **  _________________________________________________________________
69 */
70
71 /* XXX THIS STUFF NEEDS A MAJOR CLEANUP -RSE XXX */
72
73 /* this custom BIO allows us to hook SSL_write directly into 
74  * an apr_bucket_brigade and use transient buckets with the SSL
75  * malloc-ed buffer, rather than copying into a mem BIO.
76  * also allows us to pass the brigade as data is being written
77  * rather than buffering up the entire response in the mem BIO.
78  *
79  * when SSL needs to flush (e.g. SSL_accept()), it will call BIO_flush()
80  * which will trigger a call to bio_bucket_ctrl() -> BIO_bucket_flush().
81  * so we only need to flush the output ourselves if we receive an
82  * EOS or FLUSH bucket. this was not possible with the mem BIO where we
83  * had to flush all over the place not really knowing when it was required
84  * to do so.
85  */
86
87 typedef struct {
88     SSLFilterRec *frec;
89     conn_rec *c;
90     apr_bucket_brigade *bb;
91     apr_size_t length;
92     char buffer[AP_IOBUFSIZE];
93     apr_size_t blen;
94 } BIO_bucket_t;
95
96 static BIO_bucket_t *BIO_bucket_new(SSLFilterRec *frec, conn_rec *c)
97 {
98     BIO_bucket_t *b = apr_palloc(c->pool, sizeof(*b));
99
100     b->frec = frec;
101     b->c = c;
102     b->bb = apr_brigade_create(c->pool);
103     b->blen = 0;
104     b->length = 0;
105
106     return b;
107 }
108
109 #define BIO_bucket_ptr(bio) (BIO_bucket_t *)bio->ptr
110
111 static int BIO_bucket_flush(BIO *bio)
112 {
113     BIO_bucket_t *b = BIO_bucket_ptr(bio);
114
115     if (!(b->blen || b->length)) {
116         return APR_SUCCESS;
117     }
118
119     if (b->blen) {
120         apr_bucket *bucket = 
121             apr_bucket_transient_create(b->buffer,
122                                         b->blen);
123         /* we filled this buffer first so add it to the 
124          * head of the brigade
125          */
126         APR_BRIGADE_INSERT_HEAD(b->bb, bucket);
127         b->blen = 0;
128     }
129
130     b->length = 0;
131     APR_BRIGADE_INSERT_TAIL(b->bb, apr_bucket_flush_create());
132
133     return ap_pass_brigade(b->frec->pOutputFilter->next, b->bb);
134 }
135
136 static int bio_bucket_new(BIO *bio)
137 {
138     bio->shutdown = 1;
139     bio->init = 1;
140     bio->num = -1;
141     bio->ptr = NULL;
142
143     return 1;
144 }
145
146 static int bio_bucket_free(BIO *bio)
147 {
148     if (bio == NULL) {
149         return 0;
150     }
151
152     /* nothing to free here.
153      * apache will destroy the bucket brigade for us
154      */
155     return 1;
156 }
157         
158 static int bio_bucket_read(BIO *bio, char *out, int outl)
159 {
160     /* this is never called */
161     return -1;
162 }
163
164 static int bio_bucket_write(BIO *bio, const char *in, int inl)
165 {
166     BIO_bucket_t *b = BIO_bucket_ptr(bio);
167
168     /* when handshaking we'll have a small number of bytes.
169      * max size SSL will pass us here is about 16k.
170      * (16413 bytes to be exact)
171      */
172     BIO_clear_retry_flags(bio);
173
174     if (!b->length && (inl + b->blen < sizeof(b->buffer))) {
175         /* the first two SSL_writes (of 1024 and 261 bytes)
176          * need to be in the same packet (vec[0].iov_base)
177          */
178         /* XXX: could use apr_brigade_write() to make code look cleaner
179          * but this way we avoid the malloc(APR_BUCKET_BUFF_SIZE)
180          * and free() of it later
181          */
182         memcpy(&b->buffer[b->blen], in, inl);
183         b->blen += inl;
184     }
185     else {
186         /* pass along the encrypted data
187          * need to flush since we're using SSL's malloc-ed buffer 
188          * which will be overwritten once we leave here
189          */
190         apr_bucket *bucket = apr_bucket_transient_create(in, inl);
191
192         b->length += inl;
193         APR_BRIGADE_INSERT_TAIL(b->bb, bucket);
194
195         BIO_bucket_flush(bio);
196     }
197
198     return inl;
199 }
200
201 static long bio_bucket_ctrl(BIO *bio, int cmd, long num, void *ptr)
202 {
203     long ret = 1;
204     char **pptr;
205
206     BIO_bucket_t *b = BIO_bucket_ptr(bio);
207
208     switch (cmd) {
209       case BIO_CTRL_RESET:
210         b->blen = b->length = 0;
211         break;
212       case BIO_CTRL_EOF:
213         ret = (long)((b->blen + b->length) == 0);
214         break;
215       case BIO_C_SET_BUF_MEM_EOF_RETURN:
216         b->blen = b->length = (apr_size_t)num;
217         break;
218       case BIO_CTRL_INFO:
219         ret = (long)(b->blen + b->length);
220         if (ptr) {
221             pptr = (char **)ptr;
222             *pptr = (char *)&(b->buffer[0]);
223         }
224         break;
225       case BIO_CTRL_GET_CLOSE:
226         ret = (long)bio->shutdown;
227         break;
228       case BIO_CTRL_SET_CLOSE:
229         bio->shutdown = (int)num;
230         break;
231       case BIO_CTRL_WPENDING:
232         ret = 0L;
233         break;
234       case BIO_CTRL_PENDING:
235         ret = (long)(b->blen + b->length);
236         break;
237       case BIO_CTRL_FLUSH:
238         ret = (BIO_bucket_flush(bio) == APR_SUCCESS);
239         break;
240       case BIO_CTRL_DUP:
241         ret = 1;
242         break;
243         /* N/A */
244       case BIO_C_SET_BUF_MEM:
245       case BIO_C_GET_BUF_MEM_PTR:
246         /* we don't care */
247       case BIO_CTRL_PUSH:
248       case BIO_CTRL_POP:
249       default:
250         ret = 0;
251         break;
252     }
253
254     return ret;
255 }
256
257 static int bio_bucket_gets(BIO *bio, char *buf, int size)
258 {
259     /* this is never called */
260     return -1;
261 }
262
263 static int bio_bucket_puts(BIO *bio, const char *str)
264 {
265     /* this is never called */
266     return -1;
267 }
268
269 static BIO_METHOD bio_bucket_method = {
270     BIO_TYPE_MEM,
271     "APR bucket brigade",
272     bio_bucket_write,
273     bio_bucket_read,
274     bio_bucket_puts,
275     bio_bucket_gets,
276     bio_bucket_ctrl,
277     bio_bucket_new,
278     bio_bucket_free,
279 #ifdef OPENSSL_VERSION_NUMBER
280     NULL /* sslc does not have the callback_ctrl field */
281 #endif
282 };
283
284 static BIO_METHOD *BIO_s_bucket(void)
285 {
286     return &bio_bucket_method;
287 }
288
289 typedef struct {
290     int length;
291     char *value;
292 } char_buffer_t;
293
294 typedef struct {
295     SSL *ssl;
296     BIO *wbio;
297     ap_filter_t *f;
298     apr_status_t rc;
299     ap_input_mode_t mode;
300     apr_read_type_e block;
301     apr_bucket_brigade *bb;
302     apr_bucket *bucket;
303     char_buffer_t cbuf;
304 } BIO_bucket_in_t;
305
306 typedef struct {
307     BIO_bucket_in_t inbio;
308     char_buffer_t cbuf;
309     apr_pool_t *pool;
310     char buffer[AP_IOBUFSIZE];
311     SSLFilterRec *frec;
312 } ssl_io_input_ctx_t;
313
314 /*
315  * this char_buffer api might seem silly, but we don't need to copy
316  * any of this data and we need to remember the length.
317  */
318 static int char_buffer_read(char_buffer_t *buffer, char *in, int inl)
319 {
320     if (!buffer->length) {
321         return 0;
322     }
323
324     if (buffer->length > inl) {
325         /* we have have enough to fill the caller's buffer */
326         memcpy(in, buffer->value, inl);
327         buffer->value += inl;
328         buffer->length -= inl;
329     }
330     else {
331         /* swallow remainder of the buffer */
332         memcpy(in, buffer->value, buffer->length);
333         inl = buffer->length;
334         buffer->value = NULL;
335         buffer->length = 0;
336     }
337
338     return inl;
339 }
340
341 static int char_buffer_write(char_buffer_t *buffer, char *in, int inl)
342 {
343     buffer->value = in;
344     buffer->length = inl;
345     return inl;
346 }
347
348 /*
349  * this is the function called by SSL_read()
350  */
351 #define BIO_bucket_in_ptr(bio) (BIO_bucket_in_t *)bio->ptr
352
353 static int bio_bucket_in_read(BIO *bio, char *in, int inl)
354 {
355     BIO_bucket_in_t *inbio = BIO_bucket_in_ptr(bio);
356     int len = 0;
357
358     /* XXX: flush here only required for SSLv2;
359      * OpenSSL calls BIO_flush() at the appropriate times for
360      * the other protocols.
361      */
362     if (SSL_version(inbio->ssl) == SSL2_VERSION) {
363         BIO_bucket_flush(inbio->wbio);
364     }
365
366     inbio->rc = APR_SUCCESS;
367     
368     /* first use data already read from socket if any */
369     if ((len = char_buffer_read(&inbio->cbuf, in, inl))) {
370         if ((len <= inl) || inbio->mode == AP_MODE_GETLINE) {
371             return len;
372         }
373         inl -= len;
374     }
375
376     while (1) {
377         const char *buf;
378         apr_size_t buf_len = 0;
379
380         if (inbio->bucket) {
381             /* all of the data in this bucket has been read,
382              * so we can delete it now.
383              */
384             apr_bucket_delete(inbio->bucket);
385             inbio->bucket = NULL;
386         }
387
388         if (APR_BRIGADE_EMPTY(inbio->bb)) {
389             /* We will always call with READBYTES even if the user wants
390              * GETLINE.
391              */
392             inbio->rc = ap_get_brigade(inbio->f->next, inbio->bb,
393                                        AP_MODE_READBYTES, inbio->block, 
394                                        inl);
395
396             if ((inbio->rc != APR_SUCCESS) || APR_BRIGADE_EMPTY(inbio->bb))
397             {
398                 break;
399             }
400         }
401
402         inbio->bucket = APR_BRIGADE_FIRST(inbio->bb);
403
404         inbio->rc = apr_bucket_read(inbio->bucket,
405                                     &buf, &buf_len, inbio->block);
406
407         if (inbio->rc != APR_SUCCESS) {
408             apr_bucket_delete(inbio->bucket);
409             inbio->bucket = NULL;
410             return len;
411         }
412
413         if (buf_len) {
414             /* Protected against len > MAX_INT 
415              */
416             if ((len + (int)buf_len) >= inl || (int)buf_len < 0) {
417                 /* we have enough to fill the buffer.
418                  * append if we have already written to the buffer.
419                  */
420                 int nibble = inl - len;
421                 char *value = (char *)buf+nibble;
422
423                 int length = buf_len - nibble;
424                 memcpy(in + len, buf, nibble);
425
426                 char_buffer_write(&inbio->cbuf, value, length);
427                 len += nibble;
428
429                 break;
430             }
431             else {
432                 /* not enough data,
433                  * save what we have and try to read more.
434                  */
435                 memcpy(in + len, buf, buf_len);
436                 len += buf_len;
437             }
438         }
439
440         if (inbio->mode == AP_MODE_GETLINE) {
441             /* only read from the socket once in getline mode.
442              * since callers buffer size is likely much larger than
443              * the request headers.  caller can always come back for more
444              * if first read didn't get all the headers.
445              */
446             break;
447         }
448     }
449
450     return len;
451 }
452
453 static BIO_METHOD bio_bucket_in_method = {
454     BIO_TYPE_MEM,
455     "APR input bucket brigade",
456     NULL,                       /* write is never called */
457     bio_bucket_in_read,
458     NULL,                       /* puts is never called */
459     NULL,                       /* gets is never called */
460     NULL,                       /* ctrl is never called */
461     bio_bucket_new,
462     bio_bucket_free,
463 #ifdef OPENSSL_VERSION_NUMBER
464     NULL /* sslc does not have the callback_ctrl field */
465 #endif
466 };
467
468 static BIO_METHOD *BIO_s_in_bucket(void)
469 {
470     return &bio_bucket_in_method;
471 }
472
473 static const char ssl_io_filter[] = "SSL/TLS Filter";
474
475 static int ssl_io_hook_read(SSL *ssl, char *buf, int len)
476 {
477     int rc;
478
479     if (ssl == NULL) {
480         return -1;
481     }
482
483     rc = SSL_read(ssl, buf, len);
484
485     if (rc < 0) {
486         int ssl_err = SSL_get_error(ssl, rc);
487
488         if (ssl_err == SSL_ERROR_WANT_READ) {
489             /*
490              * Simulate an EINTR in case OpenSSL wants to read more.
491              * (This is usually the case when the client forces an SSL
492              * renegotation which is handled implicitly by OpenSSL.)
493              */
494             errno = EINTR;
495         }
496         else if (ssl_err == SSL_ERROR_SSL) {
497             /*
498              * Log SSL errors
499              */
500             conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
501             ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
502                     "SSL error on reading data");
503         }
504         /*
505          * XXX - Just trying to reflect the behaviour in 
506          * openssl_state_machine.c [mod_tls]. TBD
507          */
508         rc = -1;
509     }
510     return rc;
511 }
512
513 static int ssl_io_hook_write(SSL *ssl, unsigned char *buf, int len)
514 {
515     int rc;
516
517     if (ssl == NULL) {
518         return -1;
519     }
520
521     rc = SSL_write(ssl, buf, len);
522
523     if (rc < 0) {
524         int ssl_err = SSL_get_error(ssl, rc);
525
526         if (ssl_err == SSL_ERROR_WANT_WRITE) {
527             /*
528              * Simulate an EINTR in case OpenSSL wants to write more.
529              */
530             errno = EINTR;
531         }
532         else if (ssl_err == SSL_ERROR_SSL) {
533             /*
534              * Log SSL errors
535              */
536             conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
537             ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
538                     "SSL error on writing data");
539         }
540         /*
541          * XXX - Just trying to reflect the behaviour in 
542          * openssl_state_machine.c [mod_tls]. TBD
543          */
544         rc = 0;
545     }
546     return rc;
547 }
548
549 static apr_status_t ssl_filter_write(ap_filter_t *f,
550                                      const char *data,
551                                      apr_size_t len)
552 {
553     SSLFilterRec *ctx = f->ctx;
554     apr_size_t n;
555
556     /* write SSL */
557     n = ssl_io_hook_write(ctx->pssl, (unsigned char *)data, len);
558
559     if (n != len) {
560         conn_rec *c = f->c;
561         char *reason = "reason unknown";
562
563         /* XXX: probably a better way to determine this */
564         if (SSL_total_renegotiations(ctx->pssl)) {
565             reason = "likely due to failed renegotiation";
566         }
567
568         ssl_log(c->base_server, SSL_LOG_ERROR,
569                 "failed to write %d of %d bytes (%s)",
570                 n > 0 ? len - n : len, len, reason);
571
572         return APR_EINVAL;
573     }
574
575     return APR_SUCCESS;
576 }
577
578 static apr_status_t ssl_io_filter_Output(ap_filter_t *f,
579                                          apr_bucket_brigade *bb)
580 {
581     apr_status_t status = APR_SUCCESS;
582     SSLFilterRec *ctx = f->ctx;
583
584     if (!ctx->pssl) {
585         /* ssl_abort() has been called */
586         return ap_pass_brigade(f->next, bb);
587     }
588
589     while (!APR_BRIGADE_EMPTY(bb)) {
590         apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
591
592         /* If it is a flush or EOS, we need to pass this down. 
593          * These types do not require translation by OpenSSL.  
594          */
595         if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) {
596             if ((status = BIO_bucket_flush(ctx->pbioWrite)) != APR_SUCCESS) {
597                 return status;
598             }
599
600             if (APR_BUCKET_IS_EOS(bucket)) {
601                 /* By definition, nothing can come after EOS.
602                  * which also means we can pass the rest of this brigade
603                  * without creating a new one since it only contains the
604                  * EOS bucket.
605                  */
606
607                 if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
608                     return status;
609                 }
610                 break;
611             }
612             else {
613                 /* BIO_bucket_flush() already passed down a flush bucket
614                  * if there was any data to be flushed.
615                  */
616                 apr_bucket_delete(bucket);
617             }
618         }
619         else {
620             /* read filter */
621             const char *data;
622             apr_size_t len;
623
624             apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
625             status = ssl_filter_write(f, data, len);
626             apr_bucket_delete(bucket);
627
628             if (status != APR_SUCCESS) {
629                 break;
630             }
631         }
632     }
633
634     return status;
635 }
636
637 /*
638  * ctx->cbuf is leftover plaintext from ssl_io_input_getline,
639  * use what we have there first if any,
640  * then go for more by calling ssl_io_hook_read.
641  */
642 static apr_status_t ssl_io_input_read(ssl_io_input_ctx_t *ctx,
643                                       char *buf,
644                                       apr_size_t *len)
645 {
646     apr_size_t wanted = *len;
647     apr_size_t bytes = 0;
648     int rc;
649
650     *len = 0;
651
652     if ((bytes = char_buffer_read(&ctx->cbuf, buf, wanted))) {
653         *len = bytes;
654         if (ctx->inbio.mode == AP_MODE_SPECULATIVE) {
655             /* We want to rollback this read. */
656             ctx->cbuf.value -= bytes;
657             ctx->cbuf.length += bytes;
658             return APR_SUCCESS;
659         } 
660         if ((*len >= wanted) || ctx->inbio.mode == AP_MODE_GETLINE) {
661             return APR_SUCCESS;
662         }
663     }
664
665     rc = ssl_io_hook_read(ctx->frec->pssl, buf + bytes, wanted - bytes);
666
667     if (rc > 0) {
668         *len += rc;
669         if (ctx->inbio.mode == AP_MODE_SPECULATIVE) {
670             char_buffer_write(&ctx->cbuf, buf, rc);
671         }
672     }
673
674     return ctx->inbio.rc;
675 }
676
677 static apr_status_t ssl_io_input_getline(ssl_io_input_ctx_t *ctx,
678                                          char *buf,
679                                          apr_size_t *len)
680 {
681     const char *pos = NULL;
682     apr_status_t status;
683     apr_size_t tmplen = *len, buflen = *len, offset = 0;
684
685     *len = 0;
686
687     /*
688      * in most cases we get all the headers on the first SSL_read.
689      * however, in certain cases SSL_read will only get a partial
690      * chunk of the headers, so we try to read until LF is seen.
691      */
692
693     while (tmplen > 0) {
694         status = ssl_io_input_read(ctx, buf + offset, &tmplen);
695         
696         if (status != APR_SUCCESS) {
697             return status;
698         }
699
700         *len += tmplen;
701
702         if ((pos = memchr(buf, APR_ASCII_LF, *len))) {
703             break;
704         }
705
706         offset += tmplen;
707         tmplen = buflen - offset;
708     }
709
710     if (pos) {
711         char *value;
712         int length;
713         apr_size_t bytes = pos - buf;
714
715         bytes += 1;
716         value = buf + bytes;
717         length = *len - bytes;
718
719         char_buffer_write(&ctx->cbuf, value, length);
720
721         *len = bytes;
722     }
723
724     return APR_SUCCESS;
725 }
726
727 #define HTTP_ON_HTTPS_PORT \
728     "GET /mod_ssl:error:HTTP-request HTTP/1.0\r\n\r\n"
729
730 #define HTTP_ON_HTTPS_PORT_BUCKET() \
731     apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \
732                                sizeof(HTTP_ON_HTTPS_PORT) - 1)
733
734 static apr_status_t ssl_io_filter_error(ap_filter_t *f,
735                                         apr_bucket_brigade *bb,
736                                         apr_status_t status)
737 {
738     apr_bucket *bucket;
739
740     switch (status) {
741       case HTTP_BAD_REQUEST:
742             /* log the situation */
743             ssl_log(f->c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
744                     "SSL handshake failed: HTTP spoken on HTTPS port; "
745                     "trying to send HTML error page");
746
747             /* fake the request line */
748             bucket = HTTP_ON_HTTPS_PORT_BUCKET();
749             break;
750
751       default:
752         return status;
753     }
754
755     APR_BRIGADE_INSERT_TAIL(bb, bucket);
756
757     return APR_SUCCESS;
758 }
759
760 static apr_status_t ssl_io_filter_Input(ap_filter_t *f,
761                                         apr_bucket_brigade *bb,
762                                         ap_input_mode_t mode,
763                                         apr_read_type_e block,
764                                         apr_off_t readbytes)
765 {
766     apr_status_t status;
767     ssl_io_input_ctx_t *ctx = f->ctx;
768
769     apr_size_t len = sizeof(ctx->buffer);
770     int is_init = (mode == AP_MODE_INIT);
771
772     /* XXX: we don't currently support anything other than these modes. */
773     if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE && 
774         mode != AP_MODE_SPECULATIVE && mode != AP_MODE_INIT) {
775         return APR_ENOTIMPL;
776     }
777
778     ctx->inbio.mode = mode;
779     ctx->inbio.block = block;
780
781     /* XXX: we could actually move ssl_hook_process_connection to an
782      * ap_hook_process_connection but would still need to call it for
783      * AP_MODE_INIT for protocols that may upgrade the connection
784      * rather than have SSLEngine On configured.
785      */
786     status = ssl_hook_process_connection(ctx->frec);
787
788     if (status != APR_SUCCESS) {
789         return ssl_io_filter_error(f, bb, status);
790     }
791
792     if (is_init) {
793         /* protocol module needs to handshake before sending
794          * data to client (e.g. NNTP or FTP)
795          */
796         return APR_SUCCESS;
797     }
798
799     if (ctx->inbio.mode == AP_MODE_READBYTES || 
800         ctx->inbio.mode == AP_MODE_SPECULATIVE) {
801         /* Protected from truncation, readbytes < MAX_SIZE_T 
802          * FIXME: No, it's *not* protected.  -- jre */
803         if (readbytes < len) {
804             len = (apr_size_t)readbytes;
805         }
806         status = ssl_io_input_read(ctx, ctx->buffer, &len);
807     }
808     else if (ctx->inbio.mode == AP_MODE_GETLINE) {
809         status = ssl_io_input_getline(ctx, ctx->buffer, &len);
810     }
811     else {
812         /* We have no idea what you are talking about, so return an error. */
813         return APR_ENOTIMPL;
814     }
815
816     if (status != APR_SUCCESS) {
817         return ssl_io_filter_error(f, bb, status);
818     }
819
820     if (len > 0) {
821         apr_bucket *bucket =
822             apr_bucket_transient_create(ctx->buffer, len);
823         APR_BRIGADE_INSERT_TAIL(bb, bucket);
824     }
825
826     return APR_SUCCESS;
827 }
828
829 static void ssl_io_input_add_filter(SSLFilterRec *frec, conn_rec *c,
830                                     SSL *ssl)
831 {
832     ssl_io_input_ctx_t *ctx;
833
834     ctx = apr_palloc(c->pool, sizeof(*ctx));
835
836     frec->pInputFilter = ap_add_input_filter(ssl_io_filter, ctx, NULL, c);
837
838     frec->pbioRead = BIO_new(BIO_s_in_bucket());
839     frec->pbioRead->ptr = (void *)&ctx->inbio;
840
841     ctx->frec = frec;
842     ctx->inbio.ssl = ssl;
843     ctx->inbio.wbio = frec->pbioWrite;
844     ctx->inbio.f = frec->pInputFilter;
845     ctx->inbio.bb = apr_brigade_create(c->pool);
846     ctx->inbio.bucket = NULL;
847     ctx->inbio.cbuf.length = 0;
848
849     ctx->cbuf.length = 0;
850
851     ctx->pool = c->pool;
852 }
853
854 static apr_status_t ssl_io_filter_cleanup (void *data)
855 {
856     apr_status_t ret;
857     SSLFilterRec *pRec = (SSLFilterRec *)data;
858
859     if (!pRec->pssl) {
860         /* already been shutdown */
861         return APR_SUCCESS;
862     }
863
864     if ((ret = ssl_hook_CloseConnection(pRec)) != APR_SUCCESS) {
865         ap_log_error(APLOG_MARK, APLOG_ERR, ret, NULL,
866                      "Error in ssl_hook_CloseConnection");
867     }
868
869     return ret;
870 }
871
872 void ssl_io_filter_init(conn_rec *c, SSL *ssl)
873 {
874     SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
875     SSLFilterRec *filter;
876
877     filter = apr_palloc(c->pool, sizeof(SSLFilterRec));
878
879     filter->pOutputFilter   = ap_add_output_filter(ssl_io_filter,
880                                                    filter, NULL, c);
881
882     filter->pbioWrite       = BIO_new(BIO_s_bucket());
883     filter->pbioWrite->ptr  = (void *)BIO_bucket_new(filter, c);
884
885     ssl_io_input_add_filter(filter, c, ssl);
886
887     SSL_set_bio(ssl, filter->pbioRead, filter->pbioWrite);
888     filter->pssl            = ssl;
889
890     apr_pool_cleanup_register(c->pool, (void*)filter,
891                               ssl_io_filter_cleanup, apr_pool_cleanup_null);
892
893     if (sc->log_level >= SSL_LOG_DEBUG) {
894         BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
895         BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
896     }
897
898     return;
899 }
900
901 void ssl_io_filter_register(apr_pool_t *p)
902 {
903     ap_register_input_filter  (ssl_io_filter, ssl_io_filter_Input,  AP_FTYPE_CONNECTION + 5);
904     ap_register_output_filter (ssl_io_filter, ssl_io_filter_Output, AP_FTYPE_CONNECTION + 5);
905     return;
906 }
907
908 /*  _________________________________________________________________
909 **
910 **  I/O Data Debugging
911 **  _________________________________________________________________
912 */
913
914 #define DUMP_WIDTH 16
915
916 static void ssl_io_data_dump(server_rec *srvr,
917                              MODSSL_BIO_CB_ARG_TYPE *s,
918                              long len)
919 {
920     char buf[256];
921     char tmp[64];
922     int i, j, rows, trunc;
923     unsigned char ch;
924
925     trunc = 0;
926     for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
927         trunc++;
928     rows = (len / DUMP_WIDTH);
929     if ((rows * DUMP_WIDTH) < len)
930         rows++;
931     ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
932             "+-------------------------------------------------------------------------+");
933     for(i = 0 ; i< rows; i++) {
934         apr_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH);
935         apr_cpystrn(buf, tmp, sizeof(buf));
936         for (j = 0; j < DUMP_WIDTH; j++) {
937             if (((i * DUMP_WIDTH) + j) >= len)
938                 apr_cpystrn(buf+strlen(buf), "   ", sizeof(buf)-strlen(buf));
939             else {
940                 ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
941                 apr_snprintf(tmp, sizeof(tmp), "%02x%c", ch , j==7 ? '-' : ' ');
942                 apr_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
943             }
944         }
945         apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
946         for (j = 0; j < DUMP_WIDTH; j++) {
947             if (((i * DUMP_WIDTH) + j) >= len)
948                 apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
949             else {
950                 ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
951                 apr_snprintf(tmp, sizeof(tmp), "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.');
952                 apr_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
953             }
954         }
955         apr_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf));
956         ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "%s", buf);
957     }
958     if (trunc > 0)
959         ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
960                 "| %04x - <SPACES/NULS>", len + trunc);
961     ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
962             "+-------------------------------------------------------------------------+");
963     return;
964 }
965
966 long ssl_io_data_cb(BIO *bio, int cmd,
967                     MODSSL_BIO_CB_ARG_TYPE *argp,
968                     int argi, long argl, long rc)
969 {
970     SSL *ssl;
971     conn_rec *c;
972     server_rec *s;
973
974     if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL)
975         return rc;
976     if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
977         return rc;
978     s = c->base_server;
979
980     if (   cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
981         || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
982         if (rc >= 0) {
983             ssl_log(s, SSL_LOG_DEBUG,
984                     "%s: %s %ld/%d bytes %s BIO#%08X [mem: %08lX] %s",
985                     SSL_LIBRARY_NAME,
986                     (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
987                     rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"),
988                     bio, argp,
989                     (argp != NULL ? "(BIO dump follows)" : "(Oops, no memory buffer?)"));
990             if (argp != NULL)
991                 ssl_io_data_dump(s, argp, rc);
992         }
993         else {
994             ssl_log(s, SSL_LOG_DEBUG,
995                     "%s: I/O error, %d bytes expected to %s on BIO#%08X [mem: %08lX]",
996                     SSL_LIBRARY_NAME, argi,
997                     (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
998                     bio, argp);
999         }
1000     }
1001     return rc;
1002 }