summaryrefslogtreecommitdiff
path: root/libmu_auth/tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmu_auth/tls.c')
-rw-r--r--libmu_auth/tls.c89
1 files changed, 81 insertions, 8 deletions
diff --git a/libmu_auth/tls.c b/libmu_auth/tls.c
index ae2aa1d29..2c6f68e32 100644
--- a/libmu_auth/tls.c
+++ b/libmu_auth/tls.c
@@ -1,5 +1,5 @@
/* GNU Mailutils -- a suite of utilities for electronic mail
- Copyright (C) 2003-2019 Free Software Foundation, Inc.
+ Copyright (C) 2003-2024 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -92,7 +92,11 @@ _tls_stream_pull (gnutls_transport_ptr_t fd, void *buf, size_t size)
;
if (rc)
- return -1;
+ {
+ mu_debug (MU_DEBCAT_STREAM, MU_DEBUG_ERROR,
+ ("_tls_stream_pull: %s", mu_stream_strerror (stream, rc)));
+ return -1;
+ }
return rdbytes;
}
@@ -105,8 +109,8 @@ _tls_stream_push (gnutls_transport_ptr_t fd, const void *buf, size_t size)
rc = mu_stream_write (stream, buf, size, &size);
if (rc)
{
- mu_error ("_tls_stream_push: %s",
- mu_stream_strerror (stream, rc)); /* FIXME */
+ mu_debug (MU_DEBCAT_STREAM, MU_DEBUG_ERROR,
+ ("_tls_stream_push: %s", mu_stream_strerror (stream, rc)));
return -1;
}
@@ -253,16 +257,47 @@ _tls_open (mu_stream_t stream)
rc = gnutls_handshake (sp->session);
if (rc != GNUTLS_E_SUCCESS)
{
+ mu_transport_t t[2];
+
mu_debug (MU_DEBCAT_STREAM, MU_DEBUG_ERROR,
("gnutls_handshake: %s", gnutls_strerror (rc)));
sp->tls_err = rc;
+ switch (rc)
+ {
+ case GNUTLS_E_PULL_ERROR:
+ if (mu_stream_ioctl (sp->transport[0],
+ MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
+ &t) == 0 &&
+ mu_stream_err (t[0]))
+ rc = mu_stream_last_error (t[0]);
+ else
+ rc = MU_ERR_READ;
+ break;
+
+ case GNUTLS_E_PUSH_ERROR:
+ if (mu_stream_ioctl (sp->transport[1],
+ MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
+ &t) == 0 &&
+ mu_stream_err (t[1]))
+ rc = mu_stream_last_error (t[1]);
+ else
+ rc = MU_ERR_WRITE;
+ break;
+
+ default:
+ rc = MU_ERR_TLS;
+ }
+
gnutls_deinit (sp->session);
sp->session = NULL;
sp->state = state_init;
}
else
- /* FIXME: if (ssl_cafile) verify_certificate (s->session); */
- sp->state = state_open;
+ {
+ /* FIXME: if (ssl_cafile) verify_certificate (s->session); */
+ sp->state = state_open;
+ rc = 0;
+ }
break;
default:
@@ -391,7 +426,29 @@ _tls_ioctl (struct _mu_stream *stream, int code, int opcode, void *arg)
case MU_IOCTL_TCPSTREAM:
return mu_stream_ioctl (sp->transport[0], code, opcode, arg);
-
+
+ case MU_IOCTL_TIMEOUT:
+ {
+ int rc;
+
+ switch (opcode)
+ {
+ case MU_IOCTL_OP_SET:
+ rc = mu_stream_ioctl (sp->transport[0], code, opcode, arg);
+ if (rc == 0)
+ rc = mu_stream_ioctl (sp->transport[1], code, opcode, arg);
+ break;
+
+ case MU_IOCTL_OP_GET:
+ rc = mu_stream_ioctl (sp->transport[0], code, opcode, arg);
+ break;
+
+ default:
+ return EINVAL;
+ }
+ return rc;
+ }
+
default:
return ENOSYS;
}
@@ -462,6 +519,20 @@ _tls_error_string (struct _mu_stream *stream, int rc)
}
static void
+_tls_event (struct _mu_stream *str, int code,
+ unsigned long lval, void *pval)
+{
+ struct _mu_tls_stream *sp = (struct _mu_tls_stream *)str;
+ if (code == _MU_STR_EVENT_CLRFLAG && lval == _MU_STR_ERR)
+ {
+ if (sp->transport[MU_TRANSPORT_INPUT])
+ mu_stream_clearerr (sp->transport[MU_TRANSPORT_INPUT]);
+ if (sp->transport[MU_TRANSPORT_OUTPUT])
+ mu_stream_clearerr (sp->transport[MU_TRANSPORT_OUTPUT]);
+ }
+}
+
+static void
free_conf (struct mu_tls_config *conf)
{
free (conf->cert_file);
@@ -581,7 +652,9 @@ mu_tls_stream_create (mu_stream_t *pstream,
sp->stream.ctl = _tls_ioctl;
sp->stream.wait = _tls_wait;
sp->stream.error_string = _tls_error_string;
-
+ sp->stream.event_cb = _tls_event;
+ sp->stream.event_mask = _MU_STR_EVMASK (_MU_STR_EVENT_CLRFLAG);
+
mu_stream_set_buffer (strin, mu_buffer_none, 0);
mu_stream_set_buffer (strout, mu_buffer_none, 0);

Return to:

Send suggestions and report system problems to the System administrator.