Commit d01da801 d01da801a3543c80e172992ffb7d26a8d128556b by Sergey Poznyakoff

Fix TLS support in smtp.

* include/mailutils/tls.h (mu_tls_readline_fn)
(mu_tls_writeline_fn, mu_tls_stream_ctl_fn): Remove typedefs.
(mu_tls_begin): Remove prototype.
* libmu_auth/tls.c (mu_tls_begin): Remove function.
* libproto/mailer/smtp.c: Revamp STARTTLS support.
1 parent 46e3b517
......@@ -47,19 +47,6 @@ extern int mu_check_tls_environment (void);
extern int mu_init_tls_libs (void);
extern void mu_deinit_tls_libs (void);
typedef int (*mu_tls_readline_fn) (void *iodata, int n);
typedef int (*mu_tls_writeline_fn) (void *iodata, char *buf);
#define MU_TLS_SESS_GET_STREAMS 0
#define MU_TLS_SESS_SET_STREAMS 1
typedef int (*mu_tls_stream_ctl_fn) (void *iodata, int __op,
mu_stream_t *pstr);
extern int mu_tls_begin (void *iodata, mu_tls_readline_fn reader,
mu_tls_writeline_fn writer,
mu_tls_stream_ctl_fn stream_ctl,
char *keywords[]);
extern int mu_tls_enable;
#ifdef __cplusplus
......
......@@ -164,94 +164,6 @@ initialize_tls_session (void)
return session;
}
int
mu_tls_begin (void *iodata,
mu_tls_readline_fn reader,
mu_tls_writeline_fn writer,
mu_tls_stream_ctl_fn stream_ctl,
char *keywords[])
{
int i = 0;
int status;
mu_stream_t streams[2], newstr;
if (keywords == NULL)
return EINVAL;
for (i = 0; keywords[i]; i++)
{
switch (i)
{
case 0:
/*
* Send STLS/STARTTLS
*/
status = writer (iodata, keywords[i]);
if (status != 0)
{
mu_error ("mu_tls_begin: writer (0): %s", mu_strerror (status));
return status;
}
status = reader (iodata, i);
if (status != 0)
{
mu_error ("mu_tls_begin: reader (0): %s", mu_strerror (status));
return status;
}
status = stream_ctl (iodata, MU_TLS_SESS_GET_STREAMS, streams);
if (status)
return status;
status = mu_tls_client_stream_create (&newstr,
streams[0], streams[1], 0);
if (status != 0)
{
mu_error ("mu_tls_begin: mu_tls_client_stream_create(0): %s",
mu_strerror (status));
stream_ctl (iodata, MU_TLS_SESS_SET_STREAMS, streams);
return status;
}
status = mu_stream_open (newstr);
if (status != 0)
{
mu_error ("mu_tls_begin: mu_stream_open (0): %s",
mu_strerror (status));
stream_ctl (iodata, MU_TLS_SESS_SET_STREAMS, streams);
return status;
}
streams[0] = streams[1] = newstr;
stream_ctl (iodata, MU_TLS_SESS_SET_STREAMS, streams);
/* FIXME: Unref newstr */
break;
case 1:
/*
* Send CAPABILITIES request
*/
status = writer (iodata, keywords[i]);
if (status != 0)
{
mu_error ("mu_tls_begin: writer (1): %s", mu_strerror (status));
return status;
}
status = reader (iodata, i);
if (status != 0)
{
mu_error ("mu_tls_begin: reader (1): %s", mu_strerror (status));
return status;
}
break;
default:
return 1;
}
}
return 0;
}
/* ************************* TLS Stream Support **************************** */
......
......@@ -554,68 +554,40 @@ smtp_close (mu_mailer_t mailer)
return mu_stream_close (mailer->stream);
}
#ifdef WITH_TLS
/*
Client side STARTTLS support.
*/
static int
smtp_reader (void *iodata)
{
int status = 0;
smtp_t iop = iodata;
status = smtp_read_ack (iop);
CHECK_EAGAIN (iop, status);
return status;
}
static int
smtp_writer (void *iodata, char *buf)
{
smtp_t iop = iodata;
int status;
if (mu_c_strncasecmp (buf, "EHLO", 4) == 0)
status = smtp_writeline (iop, "%s %s\r\n", buf, iop->localhost);
else
status = smtp_writeline (iop, "%s\r\n", buf);
CHECK_ERROR (iop, status);
status = smtp_write (iop);
CHECK_EAGAIN (iop, status);
return status;
}
static void
smtp_stream_ctl (void *iodata, mu_stream_t * pold, mu_stream_t new)
{
smtp_t iop = iodata;
if (pold)
*pold = iop->mailer->stream;
if (new)
iop->mailer->stream = new;
}
#endif
static int
smtp_starttls (smtp_t smtp)
{
#ifdef WITH_TLS
int status;
mu_mailer_t mailer = smtp->mailer;
char *keywords[] = { "STARTTLS", NULL };
mu_stream_t newstr;
if (!mu_tls_enable || !(smtp->capa & CAPA_STARTTLS))
return -1;
smtp->capa = 0;
smtp->auth_mechs = 0;
status = mu_tls_begin (smtp, smtp_reader, smtp_writer,
smtp_stream_ctl, keywords);
status = smtp_writeline (smtp, "STARTTLS\r\n");
CHECK_ERROR (smtp, status);
status = smtp_write (smtp);
CHECK_EAGAIN (smtp, status);
status = smtp_read_ack (smtp);
CHECK_ERROR (smtp, status);
mu_stream_flush (mailer->stream);
status = mu_tls_client_stream_create (&newstr, mailer->stream,
mailer->stream, 0);
CHECK_ERROR (smtp, status);
status = mu_stream_open (newstr);
MU_DEBUG1 (mailer->debug, MU_DEBUG_PROT, "TLS negotiation %s\n",
status == 0 ? "succeeded" : "failed");
CHECK_ERROR (smtp, status);
mailer->stream = newstr;
return status;
#else
......@@ -1399,6 +1371,8 @@ smtp_parse_ehlo_ack (smtp_t smtp)
int status;
int multi;
smtp->ptr = smtp->buffer;
do
{
multi = 0;
......