]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream: If plain stream disconnects, disconnect SSL stream also.
authorTimo Sirainen <tss@iki.fi>
Thu, 8 Sep 2011 09:14:54 +0000 (12:14 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 8 Sep 2011 09:14:54 +0000 (12:14 +0300)
src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-openssl.h

index 55ba1ba26434c15c515eb123a7ccd84e4c5deff0..7d16299453ecc3bd7c2d6fb15c6f6174b9427ec7 100644 (file)
@@ -288,8 +288,9 @@ static bool ssl_iostream_bio_output(struct ssl_iostream *ssl_io)
                sent = o_stream_send(ssl_io->plain_output, buffer, bytes);
                if (sent < 0) {
                        i_assert(ssl_io->plain_output->stream_errno != 0);
-                       ssl_io->ssl_output->stream_errno =
+                       ssl_io->plain_stream_errno =
                                ssl_io->plain_output->stream_errno;
+                       ssl_io->closed = TRUE;
                        break;
                }
                i_assert(sent == (ssize_t)bytes);
@@ -308,7 +309,14 @@ static bool ssl_iostream_bio_input(struct ssl_iostream *ssl_io)
 
        while ((bytes = BIO_ctrl_get_write_guarantee(ssl_io->bio_ext)) > 0) {
                /* bytes contains how many bytes we can write to bio_ext */
-               (void)i_stream_read_data(ssl_io->plain_input, &data, &size, 0);
+               if (i_stream_read_data(ssl_io->plain_input,
+                                      &data, &size, 0) == -1 &&
+                   size == 0 && !bytes_read) {
+                       ssl_io->plain_stream_errno =
+                               ssl_io->plain_input->stream_errno;
+                       ssl_io->closed = TRUE;
+                       return FALSE;
+               }
                if (size == 0) {
                        /* wait for more input */
                        break;
@@ -377,10 +385,18 @@ int ssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret,
                        i_panic("SSL ostream buffer size not unlimited");
                        return 0;
                }
+               if (ssl_io->closed) {
+                       errno = ssl_io->plain_stream_errno;
+                       return -1;
+               }
                return 1;
        case SSL_ERROR_WANT_READ:
                ssl_io->want_read = TRUE;
                (void)ssl_iostream_bio_sync(ssl_io);
+               if (ssl_io->closed) {
+                       errno = ssl_io->plain_stream_errno;
+                       return -1;
+               }
                return ssl_io->want_read ? 0 : 1;
        case SSL_ERROR_SYSCALL:
                /* eat up the error queue */
index 190539bb4b61235dbb3c69ea7770657946104c23..a77deb4d7b1ad368454acbd27ff3c4a9ad9f3c78 100644 (file)
@@ -34,6 +34,7 @@ struct ssl_iostream {
 
        char *source;
        char *last_error;
+       int plain_stream_errno;
 
        /* copied settings */
        bool verbose, verbose_invalid_cert, require_valid_cert;
@@ -47,6 +48,7 @@ struct ssl_iostream {
        unsigned int cert_broken:1;
        unsigned int want_read:1;
        unsigned int ostream_flush_waiting_input:1;
+       unsigned int closed:1;
 };
 
 extern int dovecot_ssl_extdata_index;