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-2002 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 /* _________________________________________________________________
68 ** _________________________________________________________________
71 /* XXX THIS STUFF NEEDS A MAJOR CLEANUP -RSE XXX */
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.
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
90 apr_bucket_brigade *bb;
92 char buffer[AP_IOBUFSIZE];
96 static BIO_bucket_t *BIO_bucket_new(SSLFilterRec *frec, conn_rec *c)
98 BIO_bucket_t *b = apr_palloc(c->pool, sizeof(*b));
102 b->bb = apr_brigade_create(c->pool);
109 #define BIO_bucket_ptr(bio) (BIO_bucket_t *)bio->ptr
111 static int BIO_bucket_flush(BIO *bio)
113 BIO_bucket_t *b = BIO_bucket_ptr(bio);
115 if (!(b->blen || b->length)) {
121 apr_bucket_transient_create(b->buffer,
123 /* we filled this buffer first so add it to the
124 * head of the brigade
126 APR_BRIGADE_INSERT_HEAD(b->bb, bucket);
131 APR_BRIGADE_INSERT_TAIL(b->bb, apr_bucket_flush_create());
133 return ap_pass_brigade(b->frec->pOutputFilter->next, b->bb);
136 static int bio_bucket_new(BIO *bio)
146 static int bio_bucket_free(BIO *bio)
152 /* nothing to free here.
153 * apache will destroy the bucket brigade for us
158 static int bio_bucket_read(BIO *bio, char *out, int outl)
160 /* this is never called */
164 static int bio_bucket_write(BIO *bio, const char *in, int inl)
166 BIO_bucket_t *b = BIO_bucket_ptr(bio);
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)
172 BIO_clear_retry_flags(bio);
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)
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
182 memcpy(&b->buffer[b->blen], in, inl);
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
190 apr_bucket *bucket = apr_bucket_transient_create(in, inl);
193 APR_BRIGADE_INSERT_TAIL(b->bb, bucket);
195 BIO_bucket_flush(bio);
201 static long bio_bucket_ctrl(BIO *bio, int cmd, long num, void *ptr)
206 BIO_bucket_t *b = BIO_bucket_ptr(bio);
210 b->blen = b->length = 0;
213 ret = (long)((b->blen + b->length) == 0);
215 case BIO_C_SET_BUF_MEM_EOF_RETURN:
216 b->blen = b->length = (apr_size_t)num;
219 ret = (long)(b->blen + b->length);
222 *pptr = (char *)&(b->buffer[0]);
225 case BIO_CTRL_GET_CLOSE:
226 ret = (long)bio->shutdown;
228 case BIO_CTRL_SET_CLOSE:
229 bio->shutdown = (int)num;
231 case BIO_CTRL_WPENDING:
234 case BIO_CTRL_PENDING:
235 ret = (long)(b->blen + b->length);
238 ret = (BIO_bucket_flush(bio) == APR_SUCCESS);
244 case BIO_C_SET_BUF_MEM:
245 case BIO_C_GET_BUF_MEM_PTR:
257 static int bio_bucket_gets(BIO *bio, char *buf, int size)
259 /* this is never called */
263 static int bio_bucket_puts(BIO *bio, const char *str)
265 /* this is never called */
269 static BIO_METHOD bio_bucket_method = {
271 "APR bucket brigade",
279 #ifdef OPENSSL_VERSION_NUMBER
280 NULL /* sslc does not have the callback_ctrl field */
284 static BIO_METHOD *BIO_s_bucket(void)
286 return &bio_bucket_method;
299 ap_input_mode_t mode;
300 apr_read_type_e block;
301 apr_bucket_brigade *bb;
307 BIO_bucket_in_t inbio;
310 char buffer[AP_IOBUFSIZE];
312 } ssl_io_input_ctx_t;
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.
318 static int char_buffer_read(char_buffer_t *buffer, char *in, int inl)
320 if (!buffer->length) {
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;
331 /* swallow remainder of the buffer */
332 memcpy(in, buffer->value, buffer->length);
333 inl = buffer->length;
334 buffer->value = NULL;
341 static int char_buffer_write(char_buffer_t *buffer, char *in, int inl)
344 buffer->length = inl;
349 * this is the function called by SSL_read()
351 #define BIO_bucket_in_ptr(bio) (BIO_bucket_in_t *)bio->ptr
353 static int bio_bucket_in_read(BIO *bio, char *in, int inl)
355 BIO_bucket_in_t *inbio = BIO_bucket_in_ptr(bio);
358 /* XXX: flush here only required for SSLv2;
359 * OpenSSL calls BIO_flush() at the appropriate times for
360 * the other protocols.
362 if (SSL_version(inbio->ssl) == SSL2_VERSION) {
363 BIO_bucket_flush(inbio->wbio);
366 inbio->rc = APR_SUCCESS;
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) {
378 apr_size_t buf_len = 0;
381 /* all of the data in this bucket has been read,
382 * so we can delete it now.
384 apr_bucket_delete(inbio->bucket);
385 inbio->bucket = NULL;
388 if (APR_BRIGADE_EMPTY(inbio->bb)) {
389 /* We will always call with READBYTES even if the user wants
392 inbio->rc = ap_get_brigade(inbio->f->next, inbio->bb,
393 AP_MODE_READBYTES, inbio->block,
396 if ((inbio->rc != APR_SUCCESS) || APR_BRIGADE_EMPTY(inbio->bb))
402 inbio->bucket = APR_BRIGADE_FIRST(inbio->bb);
404 inbio->rc = apr_bucket_read(inbio->bucket,
405 &buf, &buf_len, inbio->block);
407 if (inbio->rc != APR_SUCCESS) {
408 apr_bucket_delete(inbio->bucket);
409 inbio->bucket = NULL;
414 /* Protected against len > MAX_INT
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.
420 int nibble = inl - len;
421 char *value = (char *)buf+nibble;
423 int length = buf_len - nibble;
424 memcpy(in + len, buf, nibble);
426 char_buffer_write(&inbio->cbuf, value, length);
433 * save what we have and try to read more.
435 memcpy(in + len, buf, buf_len);
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.
453 static BIO_METHOD bio_bucket_in_method = {
455 "APR input bucket brigade",
456 NULL, /* write is never called */
458 NULL, /* puts is never called */
459 NULL, /* gets is never called */
460 NULL, /* ctrl is never called */
463 #ifdef OPENSSL_VERSION_NUMBER
464 NULL /* sslc does not have the callback_ctrl field */
468 static BIO_METHOD *BIO_s_in_bucket(void)
470 return &bio_bucket_in_method;
473 static const char ssl_io_filter[] = "SSL/TLS Filter";
475 static int ssl_io_hook_read(SSL *ssl, char *buf, int len)
483 rc = SSL_read(ssl, buf, len);
486 int ssl_err = SSL_get_error(ssl, rc);
488 if (ssl_err == SSL_ERROR_WANT_READ) {
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.)
496 else if (ssl_err == SSL_ERROR_SSL) {
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");
505 * XXX - Just trying to reflect the behaviour in
506 * openssl_state_machine.c [mod_tls]. TBD
513 static int ssl_io_hook_write(SSL *ssl, unsigned char *buf, int len)
521 rc = SSL_write(ssl, buf, len);
524 int ssl_err = SSL_get_error(ssl, rc);
526 if (ssl_err == SSL_ERROR_WANT_WRITE) {
528 * Simulate an EINTR in case OpenSSL wants to write more.
532 else if (ssl_err == SSL_ERROR_SSL) {
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");
541 * XXX - Just trying to reflect the behaviour in
542 * openssl_state_machine.c [mod_tls]. TBD
549 static apr_status_t ssl_filter_write(ap_filter_t *f,
553 SSLFilterRec *ctx = f->ctx;
557 n = ssl_io_hook_write(ctx->pssl, (unsigned char *)data, len);
561 char *reason = "reason unknown";
563 /* XXX: probably a better way to determine this */
564 if (SSL_total_renegotiations(ctx->pssl)) {
565 reason = "likely due to failed renegotiation";
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);
578 static apr_status_t ssl_io_filter_Output(ap_filter_t *f,
579 apr_bucket_brigade *bb)
581 apr_status_t status = APR_SUCCESS;
582 SSLFilterRec *ctx = f->ctx;
585 /* ssl_abort() has been called */
586 return ap_pass_brigade(f->next, bb);
589 while (!APR_BRIGADE_EMPTY(bb)) {
590 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
592 /* If it is a flush or EOS, we need to pass this down.
593 * These types do not require translation by OpenSSL.
595 if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) {
596 if ((status = BIO_bucket_flush(ctx->pbioWrite)) != APR_SUCCESS) {
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
607 if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
613 /* BIO_bucket_flush() already passed down a flush bucket
614 * if there was any data to be flushed.
616 apr_bucket_delete(bucket);
624 apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
625 status = ssl_filter_write(f, data, len);
626 apr_bucket_delete(bucket);
628 if (status != APR_SUCCESS) {
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.
642 static apr_status_t ssl_io_input_read(ssl_io_input_ctx_t *ctx,
646 apr_size_t wanted = *len;
647 apr_size_t bytes = 0;
652 if ((bytes = char_buffer_read(&ctx->cbuf, buf, wanted))) {
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;
660 if ((*len >= wanted) || ctx->inbio.mode == AP_MODE_GETLINE) {
665 rc = ssl_io_hook_read(ctx->frec->pssl, buf + bytes, wanted - bytes);
669 if (ctx->inbio.mode == AP_MODE_SPECULATIVE) {
670 char_buffer_write(&ctx->cbuf, buf, rc);
674 return ctx->inbio.rc;
677 static apr_status_t ssl_io_input_getline(ssl_io_input_ctx_t *ctx,
681 const char *pos = NULL;
683 apr_size_t tmplen = *len, buflen = *len, offset = 0;
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.
694 status = ssl_io_input_read(ctx, buf + offset, &tmplen);
696 if (status != APR_SUCCESS) {
702 if ((pos = memchr(buf, APR_ASCII_LF, *len))) {
707 tmplen = buflen - offset;
713 apr_size_t bytes = pos - buf;
717 length = *len - bytes;
719 char_buffer_write(&ctx->cbuf, value, length);
727 #define HTTP_ON_HTTPS_PORT \
728 "GET /mod_ssl:error:HTTP-request HTTP/1.0\r\n\r\n"
730 #define HTTP_ON_HTTPS_PORT_BUCKET() \
731 apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \
732 sizeof(HTTP_ON_HTTPS_PORT) - 1)
734 static apr_status_t ssl_io_filter_error(ap_filter_t *f,
735 apr_bucket_brigade *bb,
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");
747 /* fake the request line */
748 bucket = HTTP_ON_HTTPS_PORT_BUCKET();
755 APR_BRIGADE_INSERT_TAIL(bb, bucket);
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,
767 ssl_io_input_ctx_t *ctx = f->ctx;
769 apr_size_t len = sizeof(ctx->buffer);
770 int is_init = (mode == AP_MODE_INIT);
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) {
778 ctx->inbio.mode = mode;
779 ctx->inbio.block = block;
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.
786 status = ssl_hook_process_connection(ctx->frec);
788 if (status != APR_SUCCESS) {
789 return ssl_io_filter_error(f, bb, status);
793 /* protocol module needs to handshake before sending
794 * data to client (e.g. NNTP or FTP)
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;
806 status = ssl_io_input_read(ctx, ctx->buffer, &len);
808 else if (ctx->inbio.mode == AP_MODE_GETLINE) {
809 status = ssl_io_input_getline(ctx, ctx->buffer, &len);
812 /* We have no idea what you are talking about, so return an error. */
816 if (status != APR_SUCCESS) {
817 return ssl_io_filter_error(f, bb, status);
822 apr_bucket_transient_create(ctx->buffer, len);
823 APR_BRIGADE_INSERT_TAIL(bb, bucket);
829 static void ssl_io_input_add_filter(SSLFilterRec *frec, conn_rec *c,
832 ssl_io_input_ctx_t *ctx;
834 ctx = apr_palloc(c->pool, sizeof(*ctx));
836 frec->pInputFilter = ap_add_input_filter(ssl_io_filter, ctx, NULL, c);
838 frec->pbioRead = BIO_new(BIO_s_in_bucket());
839 frec->pbioRead->ptr = (void *)&ctx->inbio;
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;
849 ctx->cbuf.length = 0;
854 static apr_status_t ssl_io_filter_cleanup (void *data)
857 SSLFilterRec *pRec = (SSLFilterRec *)data;
860 /* already been shutdown */
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");
872 void ssl_io_filter_init(conn_rec *c, SSL *ssl)
874 SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
875 SSLFilterRec *filter;
877 filter = apr_palloc(c->pool, sizeof(SSLFilterRec));
879 filter->pOutputFilter = ap_add_output_filter(ssl_io_filter,
882 filter->pbioWrite = BIO_new(BIO_s_bucket());
883 filter->pbioWrite->ptr = (void *)BIO_bucket_new(filter, c);
885 ssl_io_input_add_filter(filter, c, ssl);
887 SSL_set_bio(ssl, filter->pbioRead, filter->pbioWrite);
890 apr_pool_cleanup_register(c->pool, (void*)filter,
891 ssl_io_filter_cleanup, apr_pool_cleanup_null);
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);
901 void ssl_io_filter_register(apr_pool_t *p)
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);
908 /* _________________________________________________________________
910 ** I/O Data Debugging
911 ** _________________________________________________________________
914 #define DUMP_WIDTH 16
916 static void ssl_io_data_dump(server_rec *srvr,
917 MODSSL_BIO_CB_ARG_TYPE *s,
922 int i, j, rows, trunc;
926 for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
928 rows = (len / DUMP_WIDTH);
929 if ((rows * DUMP_WIDTH) < len)
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));
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));
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));
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));
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);
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 "+-------------------------------------------------------------------------+");
966 long ssl_io_data_cb(BIO *bio, int cmd,
967 MODSSL_BIO_CB_ARG_TYPE *argp,
968 int argi, long argl, long rc)
974 if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL)
976 if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
980 if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
981 || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
983 ssl_log(s, SSL_LOG_DEBUG,
984 "%s: %s %ld/%d bytes %s BIO#%08X [mem: %08lX] %s",
986 (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
987 rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"),
989 (argp != NULL ? "(BIO dump follows)" : "(Oops, no memory buffer?)"));
991 ssl_io_data_dump(s, argp, rc);
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"),