Commit cab81060 cab810601ec85691494b1d3424b171b06b0c2348 by Sergey Poznyakoff

Re-implement server TLS support.

STLS in pop3d is already working.

* include/mailutils/sys/tls-stream.h: New header.
* include/mailutils/tls.h (mu_tls_stream_create)
(mu_tls_stream_create_client)
(mu_tls_stream_create_client_from_tcp): Remove.
(mu_tls_server_stream_create, mu_tls_client_stream_create): New
protos.
* libmu_auth/tls.c: Rewrite.

* imap4d/util.c: Use mu_tls_server_stream_create.
* libproto/pop/mbox.c: Use mu_tls_server_stream_create/
mu_tls_client_stream_create.
* libproto/pop/pop3_stls.c: Use mu_tls_client_stream_create.
* libproto/imap/folder.c: Use mu_tls_client_stream_create.

* pop3d/capa.c (pop3d_capa): CAPA is allowed in both states.
* pop3d/extra.c (pop3d_setio): Rewrite.
1 parent 400fdaac
......@@ -893,7 +893,7 @@ imap4d_init_tls_server ()
mu_stream_t stream;
int rc;
rc = mu_tls_stream_create (&stream, istream, ostream, 0);
rc = mu_tls_server_stream_create (&stream, istream, ostream, 0);
if (rc)
return 0;
......
......@@ -34,5 +34,6 @@ sysinclude_HEADERS = \
streamref.h\
streamtrans.h\
stream.h\
tls-stream.h\
pop3.h\
nntp.h
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010 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 License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _MAILUTILS_SYS_TLS_STREAM_H
# define _MAILUTILS_SYS_TLS_STREAM_H
# include <mailutils/types.h>
# include <mailutils/stream.h>
# include <mailutils/sys/stream.h>
enum _mu_tls_stream_state
{
state_init,
state_open,
state_closed,
state_destroyed
};
struct _mu_tls_io_stream
{
struct _mu_stream stream;
mu_stream_t transport;
struct _mu_tls_stream *up;
};
struct _mu_tls_stream
{
struct _mu_stream stream;
enum _mu_tls_stream_state state;
gnutls_session session;
int tls_err;
mu_stream_t transport[2];
};
struct _mu_tls_stream_s
{
struct _mu_stream stream;
enum _mu_tls_stream_state state;
gnutls_session session;
int tls_err;
mu_stream_t transport;
};
#endif
......@@ -36,15 +36,12 @@ struct mu_tls_module_config
extern int mu_tls_module_init (enum mu_gocs_op, void *);
extern int mu_tls_stream_create (mu_stream_t *stream,
mu_stream_t strin, mu_stream_t strout,
int flags);
extern int mu_tls_stream_create_client (mu_stream_t *stream,
extern int mu_tls_server_stream_create (mu_stream_t *stream,
mu_stream_t strin, mu_stream_t strout,
int flags);
extern int mu_tls_client_stream_create (mu_stream_t *stream,
mu_stream_t strin, mu_stream_t strout,
int flags);
extern int mu_tls_stream_create_client_from_tcp (mu_stream_t *stream,
mu_stream_t tcp_str,
int flags);
extern int mu_check_tls_environment (void);
extern int mu_init_tls_libs (void);
......
......@@ -688,10 +688,12 @@ folder_imap_open (mu_folder_t folder, int flags)
CHECK_EAGAIN (f_imap, status);
CHECK_ERROR_CLOSE (folder, f_imap, status);
status = mu_tls_stream_create_client_from_tcp (&newstr, folder->stream, 0);
status = mu_tls_client_stream_create (&newstr,
folder->stream,
folder->stream, 0);
if (status != 0)
{
mu_error ("folder_imap_open: mu_tls_stream_create_client_from_tcp: %s",
mu_error ("folder_imap_open: mu_tls_client_stream_create: %s",
mu_strerror (status));
return status;
}
......
......@@ -824,8 +824,11 @@ pop_open (mu_mailbox_t mbox, int flags)
/* Create the networking stack. */
if (mbox->stream == NULL)
{
status = mu_tcp_stream_create (&mbox->stream, host, port, mbox->flags);
status = mu_tcp_stream_create (&mbox->stream, host, port,
mbox->flags);
CHECK_ERROR (mpd, status);
/* FIXME: How to configure the buffer size? */
mu_stream_set_buffer (mbox->stream, mu_buffer_line, 1024);
#ifdef WITH_TLS
if (mpd->pops)
......@@ -836,19 +839,18 @@ pop_open (mu_mailbox_t mbox, int flags)
CHECK_EAGAIN (mpd, status);
CHECK_ERROR_CLOSE (mbox, mpd, status);
status = mu_tls_stream_create_client_from_tcp (&newstr, mbox->stream, 0);
status = mu_tls_client_stream_create (&newstr,
mbox->stream,
mbox->stream, 0);
if (status != 0)
{
mu_error ("pop_open: mu_tls_stream_create_client_from_tcp: %s",
mu_error ("pop_open: mu_tls_client_stream_create: %s",
mu_strerror (status));
return status;
}
mbox->stream = newstr;
}
#endif /* WITH_TLS */
/* Using the awkward mu_stream_t buffering. */
mu_stream_setbufsiz (mbox->stream, BUFSIZ);
}
else
{
......
......@@ -66,7 +66,9 @@ mu_pop3_stls (mu_pop3_t pop3)
MU_POP3_CHECK_EAGAIN (pop3, status);
mu_pop3_debug_ack (pop3);
MU_POP3_CHECK_OK (pop3);
status = mu_tls_stream_create_client_from_tcp (&tls_stream, pop3->carrier, 0);
status = mu_tls_client_stream_create (&tls_stream,
pop3->carrier,
pop3->carrier, 0);
MU_POP3_CHECK_ERROR (pop3, status);
pop3->carrier = tls_stream;
pop3->state = MU_POP3_STLS_CONNECT;
......
......@@ -32,9 +32,6 @@ pop3d_capa (char *arg)
if (strlen (arg) != 0)
return ERR_BAD_ARGS;
if (state != initial_state && state != TRANSACTION)
return ERR_WRONG_STATE;
pop3d_outf ("+OK Capability list follows\n");
pop3d_outf ("TOP\n");
pop3d_outf ("USER\n");
......
......@@ -126,6 +126,14 @@ pop3d_abquit (int reason)
exit (code);
}
/* Keeps the *real* output stream. Ostream is a RFC822 filter built over
real_ostream, or even over a TLS stream, which in turn is based on this
real_ostream.
FIXME: This is sorta kludge: we could use MU_IOCTL_GET_TRANSPORT call
to retrieve the bottom-level stream, if filter streams supported it.
*/
static mu_stream_t real_ostream;
void
pop3d_setio (FILE *in, FILE *out)
{
......@@ -136,14 +144,17 @@ pop3d_setio (FILE *in, FILE *out)
if (!out)
pop3d_abquit (ERR_NO_OFILE);
if (mu_stdio_stream_create (&istream, fileno (in), MU_STREAM_NO_CLOSE))
if (mu_stdio_stream_create (&istream, fileno (in),
MU_STREAM_READ | MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_IFILE);
mu_stream_set_buffer (istream, mu_buffer_line, 1024);
if (mu_stdio_stream_create (&str, fileno (out), MU_STREAM_NO_CLOSE))
if (mu_stdio_stream_create (&str, fileno (out),
MU_STREAM_WRITE | MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_OFILE);
real_ostream = str;
if (mu_filter_create (&ostream, str, "rfc822", MU_FILTER_ENCODE,
MU_STREAM_WRITE|MU_STREAM_NO_CLOSE))
MU_STREAM_WRITE | MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_IFILE);
mu_stream_set_buffer (ostream, mu_buffer_line, 1024);
}
......@@ -154,8 +165,8 @@ pop3d_init_tls_server ()
{
mu_stream_t stream;
int rc;
rc = mu_tls_stream_create (&stream, istream, ostream, 0);
rc = mu_tls_server_stream_create (&stream, istream, real_ostream, 0);
if (rc)
return 0;
......@@ -167,7 +178,12 @@ pop3d_init_tls_server ()
return 0;
}
istream = ostream = stream;
istream = stream;
mu_stream_destroy (&ostream);
if (mu_filter_create (&ostream, stream, "rfc822", MU_FILTER_ENCODE,
MU_STREAM_WRITE | MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_IFILE);
mu_stream_set_buffer (ostream, mu_buffer_line, 1024);
return 1;
}
#endif
......