summaryrefslogtreecommitdiff
path: root/imap4d/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'imap4d/io.c')
-rw-r--r--imap4d/io.c143
1 files changed, 96 insertions, 47 deletions
diff --git a/imap4d/io.c b/imap4d/io.c
index d24cd210c..238c1a4b8 100644
--- a/imap4d/io.c
+++ b/imap4d/io.c
@@ -60,49 +60,34 @@ io_setio (int ifd, int ofd, struct mu_tls_config *tls_conf)
if (ofd == -1)
imap4d_bye (ERR_NO_OFILE);
- if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ))
- imap4d_bye (ERR_STREAM_CREATE);
- mu_stream_set_buffer (istream, mu_buffer_line, 0);
-
- if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE))
- imap4d_bye (ERR_STREAM_CREATE);
- mu_stream_set_buffer (ostream, mu_buffer_line, 0);
-
- /* Combine the two streams into an I/O one. */
if (tls_conf)
{
- /* Set timeouts for TLS handshake */
- struct timeval tv;
-
- tv.tv_sec = 10;
- tv.tv_usec = 0;
- mu_stream_ioctl (istream, MU_IOCTL_TIMEOUT, MU_IOCTL_OP_SET, &tv);
- mu_stream_ioctl (ostream, MU_IOCTL_TIMEOUT, MU_IOCTL_OP_SET, &tv);
-
- rc = mu_tls_stream_create (&str, istream, ostream,
- tls_conf,
- MU_TLS_SERVER,
- 0);
+ rc = mu_tlsfd_stream_create (&str, ifd, ofd, tls_conf, MU_TLS_SERVER, 0);
if (rc)
{
mu_error (_("failed to create TLS stream: %s"), mu_strerror (rc));
imap4d_bye (ERR_STREAM_CREATE);
}
-
- /* Reset timeouts */
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- mu_stream_ioctl (istream, MU_IOCTL_TIMEOUT, MU_IOCTL_OP_SET, &tv);
- mu_stream_ioctl (ostream, MU_IOCTL_TIMEOUT, MU_IOCTL_OP_SET, &tv);
-
log_cipher (str);
}
- else if (mu_iostream_create (&str, istream, ostream))
- imap4d_bye (ERR_STREAM_CREATE);
-
- mu_stream_unref (istream);
- mu_stream_unref (ostream);
+ else
+ {
+ if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ))
+ imap4d_bye (ERR_STREAM_CREATE);
+ mu_stream_set_buffer (istream, mu_buffer_line, 0);
+
+ if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE))
+ imap4d_bye (ERR_STREAM_CREATE);
+ mu_stream_set_buffer (ostream, mu_buffer_line, 0);
+
+ /* Combine the two streams into an I/O one. */
+ if (mu_iostream_create (&str, istream, ostream))
+ imap4d_bye (ERR_STREAM_CREATE);
+ mu_stream_unref (istream);
+ mu_stream_unref (ostream);
+ }
+
/* Convert all writes to CRLF form.
There is no need to convert reads, as the code ignores extra \r anyway.
*/
@@ -141,23 +126,44 @@ io_setio (int ifd, int ofd, struct mu_tls_config *tls_conf)
int
imap4d_init_tls_server (struct mu_tls_config *tls_conf)
{
- mu_stream_t tlsstream, stream[2];
+ mu_stream_t tlsstream, stream[2], tstr, istr;
+ mu_transport_t t[2];
+ int ifd, ofd;
int rc;
rc = mu_stream_ioctl (iostream, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, stream);
if (rc)
{
- mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
+ mu_error (_("%s failed: %s"), "MU_IOCTL_SUBSTREAM",
mu_stream_strerror (iostream, rc));
return 1;
}
- rc = mu_tls_stream_create (&tlsstream, stream[0], stream[1],
- tls_conf,
- MU_TLS_SERVER,
- 0);
- mu_stream_unref (stream[0]);
- mu_stream_unref (stream[1]);
+ rc = mu_stream_ioctl (stream[MU_TRANSPORT_INPUT], MU_IOCTL_TRANSPORT,
+ MU_IOCTL_OP_GET, t);
+ if (rc)
+ {
+ mu_error (_("%s failed: %s"), "MU_IOCTL_TRANSPORT",
+ mu_stream_strerror (iostream, rc));
+ return 1;
+ }
+ ifd = (int) (intptr_t) t[0];
+
+ rc = mu_stream_ioctl (stream[MU_TRANSPORT_OUTPUT], MU_IOCTL_TRANSPORT,
+ MU_IOCTL_OP_GET, t);
+ if (rc)
+ {
+ mu_error (_("%s failed: %s"), "MU_IOCTL_TRANSPORT",
+ mu_stream_strerror (iostream, rc));
+ return 1;
+ }
+ ofd = (int) (intptr_t) t[0];
+
+ rc = mu_tlsfd_stream_create (&tlsstream, ifd, ofd,
+ tls_conf,
+ MU_TLS_SERVER,
+ 0);
+
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, _("cannot open TLS stream: %s"),
@@ -167,17 +173,60 @@ imap4d_init_tls_server (struct mu_tls_config *tls_conf)
log_cipher (tlsstream);
- stream[0] = stream[1] = tlsstream;
+ t[0] = (mu_transport_t) -1;
+ mu_stream_ioctl (stream[MU_TRANSPORT_INPUT], MU_IOCTL_TRANSPORT,
+ MU_IOCTL_OP_SET, t);
+ t[0] = (mu_transport_t) -1;
+ mu_stream_ioctl (stream[MU_TRANSPORT_OUTPUT], MU_IOCTL_TRANSPORT,
+ MU_IOCTL_OP_SET, t);
+
+ mu_stream_unref (stream[0]);
+ mu_stream_unref (stream[1]);
- rc = mu_stream_ioctl (iostream, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_SET, stream);
+ /*
+ * Find the iostream and replace it with the TLS stream.
+ * Unless transcript is enabled the iostream variable refers to a
+ * CRLF filter, and its sub-stream is the iostream object. If transcript
+ * is enabled, the treanscript stream is added on top and iostream refers
+ * to it.
+ *
+ * The loop below uses the fact that iostream is the only stream in
+ * mailutils that returns *both* transport streams on MU_IOCTL_TOPSTREAM/
+ * MU_IOCTL_OP_GET ioctl. Rest of streams that support MU_IOCTL_TOPSTREAM,
+ * return the transport stream in stream[0] and NULL in stream[1].
+ */
+ tstr = NULL;
+ istr = iostream;
+ while ((rc = mu_stream_ioctl (istr,
+ MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET,
+ stream)) == 0
+ && stream[1] == NULL)
+ {
+ tstr = istr;
+ istr = stream[0];
+ mu_stream_unref (istr);
+ }
+
if (rc)
{
- mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
- mu_stream_strerror (iostream, rc));
- imap4d_bye (ERR_STREAM_CREATE);
+ mu_error ("%s", _("INTERNAL ERROR: cannot locate iostream"));
+ return 1;
}
- mu_stream_unref (tlsstream);
+ mu_stream_unref (stream[0]);
+ mu_stream_unref (stream[1]);
+
+ stream[0] = tlsstream;
+ stream[1] = NULL;
+ rc = mu_stream_ioctl (tstr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_SET, stream);
+ if (rc)
+ {
+ mu_error (_("INTERNAL ERROR: failed to install TLS stream: %s"),
+ mu_strerror (rc));
+ return 1;
+ }
+ mu_stream_unref (tlsstream);
+
return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.