summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-11-04 21:30:38 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-11-04 21:44:56 +0200
commite1233d5516f48cd7d786a69d4eebd40e73d95d45 (patch)
tree38692d813e645ac60bfababee4c5f7ec7f8cede9
parentbad3c6c3a982f65af0fe137d1e5b7a98d13bb9d5 (diff)
downloadmailutils-e1233d5516f48cd7d786a69d4eebd40e73d95d45.tar.gz
mailutils-e1233d5516f48cd7d786a69d4eebd40e73d95d45.tar.bz2
Implement pop3s and imap4s in respective servers.
* comsat/comsat.c (comsat_prefork,comsat_connection): Change signatures. * imap4d/imap4d.c: Implement imaps. * imap4d/imap4d.h (io_setio): Change signature. (tls_encryption_on): New proto. * imap4d/io.c (io_setio): Change signature. Initialize TLS stream if requested. * imap4d/starttls.c (tls_encryption_on): New function. * include/mailutils/server.h (mu_srv_config): New struct. (mu_m_server_conn_fp, mu_m_server_prefork_fp): Remove typedefs. (mu_m_server_handler_fp): New typedef. (mu_m_server_set_conn): Change signature. (mu_m_server_set_prefork): Change signature. (mu_m_server_set_app_data_size) (mu_m_server_set_config_size): New prototype. (mu_m_server_cfg_init): Change signature. * include/mailutils/tls.h (mu_init_tls_libs): Change signature. * lib/tcpwrap.c: Include tcpwrap.h (mu_tcp_wrapper_daemon): Fix declaration. (mu_tcp_wrapper_prefork): Change signature. * lib/tcpwrap.h (mu_tcp_wrapper_prefork): Change signature * libmailutils/server/msrv.c (_mu_m_server) <conn,prefork>: Change data type. All uses updated. <app_data_size>: New member. (m_srv_config): Remove struct. Replaced with mu_srv_config from tls.h (mu_m_server_set_conn): Change signature. (mu_m_server_set_prefork): Change signature. (mu_m_server_set_app_data_size) (mu_m_server_set_config_size): New functions. (add_server): Allocate app_data_size additional bytes of data. (mu_m_server_cfg_init): Take one argument. * libmu_auth/tls.c (mu_tls_module_init): Update call to mu_init_tls_libs. Don't call mu_file_safety_check with NULL argument. (mu_init_tls_libs): Rewrite. Prepare x509 here, instead of doing it each time a TLS stream is created. (mu_deinit_tls_libs): Free x509, if exists. (_tls_server_open): Update call to mu_init_tls_libs. Remove x509 initialization. * libmu_cfg/tls.c (cb2_safety_checks): Fix typos. * maidag/lmtp.c (lmtp_connection): Change signature. * maidag/maidag.c (main): Update call to mu_m_server_cfg_init. * maidag/maidag.h (lmtp_connection): Change signature. * pop3d/extra.c (pop3d_setio): Initialize TLS stream, if requested. * pop3d/pop3d.c: Implement pops. * pop3d/pop3d.h (pop3d_setio): Change prototype.
-rw-r--r--comsat/comsat.c16
-rw-r--r--imap4d/imap4d.c38
-rw-r--r--imap4d/imap4d.h3
-rw-r--r--imap4d/io.c17
-rw-r--r--imap4d/starttls.c28
-rw-r--r--include/mailutils/server.h30
-rw-r--r--include/mailutils/tls.h2
-rw-r--r--lib/tcpwrap.c8
-rw-r--r--lib/tcpwrap.h6
-rw-r--r--libmailutils/base/filesafety.c4
-rw-r--r--libmailutils/server/msrv.c74
-rw-r--r--libmu_auth/tls.c93
-rw-r--r--libmu_cfg/tls.c6
-rw-r--r--maidag/lmtp.c9
-rw-r--r--maidag/maidag.c2
-rw-r--r--maidag/maidag.h5
-rw-r--r--pop3d/extra.c23
-rw-r--r--pop3d/pop3d.c43
-rw-r--r--pop3d/pop3d.h2
19 files changed, 261 insertions, 148 deletions
diff --git a/comsat/comsat.c b/comsat/comsat.c
index e9a5a220c..ec73d52a1 100644
--- a/comsat/comsat.c
+++ b/comsat/comsat.c
@@ -320,7 +320,8 @@ static unsigned overflow_count = 0; /* Number of overflows detected during
the current interval */
int
-comsat_prefork (int fd, void *data, struct sockaddr *s, int size)
+comsat_prefork (int fd, struct sockaddr *s, int size,
+ struct mu_srv_config *pconf, void *data)
{
int retval = 0;
time_t now;
@@ -367,15 +368,14 @@ comsat_prefork (int fd, void *data, struct sockaddr *s, int size)
int
comsat_connection (int fd, struct sockaddr *sa, int salen,
- void *data, mu_ip_server_t srv,
- time_t to, int transcript)
+ struct mu_srv_config *pconf, void *data)
{
char *buffer;
size_t rdlen, size;
- if (mu_udp_server_get_rdata (srv, &buffer, &rdlen))
+ if (mu_udp_server_get_rdata (pconf->tcpsrv, &buffer, &rdlen))
return 0;
- if (transcript)
+ if (pconf->transcript)
{
char *p = mu_sockaddr_to_astr (sa, salen);
mu_diag_output (MU_DIAG_INFO,
@@ -386,10 +386,10 @@ comsat_connection (int fd, struct sockaddr *sa, int salen,
mu_diag_output (MU_DIAG_INFO, "string: %s", buffer);
free (p);
}
- mu_udp_server_get_bufsize (srv, &size);
+ mu_udp_server_get_bufsize (pconf->tcpsrv, &size);
if (size < rdlen + 1)
{
- int rc = mu_udp_server_set_bufsize (srv, rdlen + 1);
+ int rc = mu_udp_server_set_bufsize (pconf->tcpsrv, rdlen + 1);
if (rc)
{
mu_error (_("cannot resize buffer: %s"), mu_strerror (rc));
@@ -560,7 +560,7 @@ main (int argc, char **argv)
mu_argp_init (NULL, NULL);
comsat_init ();
mu_acl_cfg_init ();
- mu_m_server_cfg_init ();
+ mu_m_server_cfg_init (NULL);
mu_m_server_create (&server, program_version);
mu_m_server_set_type (server, MU_IP_UDP);
mu_m_server_set_conn (server, comsat_connection);
diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index 035690aa1..65d678c4d 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -93,7 +93,7 @@ static const char *imap4d_capa[] = {
NULL
};
-static int imap4d_mainloop (int, int);
+static int imap4d_mainloop (int, int, int);
static error_t
imap4d_parse_opt (int key, char *arg, struct argp_state *state)
@@ -242,6 +242,20 @@ cb_mailbox_mode (void *data, mu_config_value_t *val)
return 0;
}
+struct imap4d_srv_config
+{
+ struct mu_srv_config m_cfg;
+ int tls;
+};
+
+static struct mu_cfg_param imap4d_srv_param[] = {
+ { "tls", mu_cfg_bool, NULL, mu_offsetof (struct imap4d_srv_config, tls),
+ NULL,
+ N_("Use TLS encryption for this server")
+ },
+ { NULL }
+};
+
static struct mu_cfg_param imap4d_cfg_param[] = {
{ "homedir", mu_cfg_string, &modify_homedir, 0, NULL,
N_("Modify home directory.") },
@@ -396,7 +410,7 @@ imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
}
static int
-imap4d_mainloop (int ifd, int ofd)
+imap4d_mainloop (int ifd, int ofd, int tls)
{
imap4d_tokbuf_t tokp;
char *text;
@@ -435,7 +449,7 @@ imap4d_mainloop (int ifd, int ofd)
imap4d_child_signal_setup (imap4d_child_signal);
}
- io_setio (ifd, ofd);
+ io_setio (ifd, ofd, tls);
if (imap4d_preauth_setup (ifd) == 0)
{
@@ -478,13 +492,14 @@ imap4d_mainloop (int ifd, int ofd)
}
int
-imap4d_connection (int fd, struct sockaddr *sa, int salen, void *data,
- mu_ip_server_t srv, time_t timeout, int transcript)
+imap4d_connection (int fd, struct sockaddr *sa, int salen,
+ struct mu_srv_config *pconf, void *data)
{
- idle_timeout = timeout;
- if (imap4d_transcript != transcript)
- imap4d_transcript = transcript;
- imap4d_mainloop (fd, fd);
+ struct imap4d_srv_config *cfg = (struct imap4d_srv_config *) pconf;
+
+ idle_timeout = pconf->timeout;
+ imap4d_transcript = pconf->transcript;
+ imap4d_mainloop (fd, fd, cfg->tls);
return 0;
}
@@ -559,11 +574,12 @@ main (int argc, char **argv)
mu_tcpwrapper_cfg_init ();
manlock_cfg_init ();
mu_acl_cfg_init ();
- mu_m_server_cfg_init ();
+ mu_m_server_cfg_init (imap4d_srv_param);
mu_argp_init (NULL, NULL);
mu_m_server_create (&server, program_version);
+ mu_m_server_set_config_size (server, sizeof (struct imap4d_srv_config));
mu_m_server_set_conn (server, imap4d_connection);
mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork);
mu_m_server_set_mode (server, MODE_INTERACTIVE);
@@ -669,7 +685,7 @@ main (int argc, char **argv)
{
/* Make sure we are in the root directory. */
chdir ("/");
- status = imap4d_mainloop (MU_STDIN_FD, MU_STDOUT_FD);
+ status = imap4d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, 0);
}
if (status)
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index 5245e2fe6..3ece1401e 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -220,7 +220,7 @@ extern int io_stream_completion_response (mu_stream_t str,
const char *format, ...)
MU_PRINTFLIKE(4,5);
void io_getline (char **pbuf, size_t *psize, size_t *pnbytes);
-void io_setio (int, int);
+void io_setio (int, int, int);
void io_flush (void);
int io_wait_input (int);
@@ -297,6 +297,7 @@ extern int imap4d_select_status (void);
#ifdef WITH_TLS
extern int imap4d_starttls (struct imap4d_command *, imap4d_tokbuf_t);
extern void starttls_init (void);
+void tls_encryption_on (void);
#endif /* WITH_TLS */
extern int imap4d_status (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_store (struct imap4d_command *, imap4d_tokbuf_t);
diff --git a/imap4d/io.c b/imap4d/io.c
index 20336384e..c0535fd38 100644
--- a/imap4d/io.c
+++ b/imap4d/io.c
@@ -20,7 +20,7 @@
mu_stream_t iostream;
void
-io_setio (int ifd, int ofd)
+io_setio (int ifd, int ofd, int tls)
{
mu_stream_t str, istream, ostream;
@@ -38,6 +38,21 @@ io_setio (int ifd, int ofd)
mu_stream_set_buffer (ostream, mu_buffer_line, 0);
/* Combine the two streams into an I/O one. */
+#ifdef WITH_TLS
+ if (tls)
+ {
+ int rc = mu_tls_server_stream_create (&str, istream, ostream, 0);
+ if (rc)
+ {
+ mu_stream_unref (istream);
+ mu_stream_unref (ostream);
+ mu_error (_("failed to create TLS stream: %s"), mu_strerror (rc));
+ imap4d_bye (ERR_STREAM_CREATE);
+ }
+ tls_encryption_on ();
+ }
+ else
+#endif
if (mu_iostream_create (&str, istream, ostream))
imap4d_bye (ERR_STREAM_CREATE);
diff --git a/imap4d/starttls.c b/imap4d/starttls.c
index 5bceb1d6e..5539903d1 100644
--- a/imap4d/starttls.c
+++ b/imap4d/starttls.c
@@ -47,18 +47,9 @@ imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok)
status = io_completion_response (command, RESP_OK, "Begin TLS negotiation");
io_flush ();
- tls_done = imap4d_init_tls_server () == 0;
- if (tls_done)
- {
- imap4d_capability_remove (IMAP_CAPA_STARTTLS);
-
- login_disabled = 0;
- imap4d_capability_remove (IMAP_CAPA_LOGINDISABLED);
-
- tls_required = 0;
- imap4d_capability_remove (IMAP_CAPA_XTLSREQUIRED);
- }
+ if (imap4d_init_tls_server () == 0)
+ tls_encryption_on ();
else
{
mu_diag_output (MU_DIAG_ERROR, _("session terminated"));
@@ -70,11 +61,24 @@ imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok)
}
void
+tls_encryption_on ()
+{
+ tls_done = 1;
+ imap4d_capability_remove (IMAP_CAPA_STARTTLS);
+
+ login_disabled = 0;
+ imap4d_capability_remove (IMAP_CAPA_LOGINDISABLED);
+
+ tls_required = 0;
+ imap4d_capability_remove (IMAP_CAPA_XTLSREQUIRED);
+}
+
+void
starttls_init ()
{
tls_available = mu_check_tls_environment ();
if (tls_available)
- tls_available = mu_init_tls_libs ();
+ tls_available = mu_init_tls_libs (1);
if (tls_available)
imap4d_capability_add (IMAP_CAPA_STARTTLS);
}
diff --git a/include/mailutils/server.h b/include/mailutils/server.h
index c5da97e43..896ebee69 100644
--- a/include/mailutils/server.h
+++ b/include/mailutils/server.h
@@ -80,20 +80,31 @@ int mu_udp_server_get_rdata (mu_ip_server_t srv, char **pbuf,
/* m-server */
+
+struct mu_srv_config /* Configuration data for a single TCP server. */
+{
+ mu_m_server_t msrv; /* Parent m-server. */
+ mu_ip_server_t tcpsrv; /* TCP server these data are for. */
+ mu_acl_t acl; /* Access control list for this server. */
+ int single_process; /* Should it run as a single process? */
+ int transcript; /* Enable session transcript. */
+ time_t timeout; /* Idle timeout for this server. */
+ /* Application-dependent data may follow */
+};
+
+
typedef struct mu_m_server_connect_data mu_m_server_connect_data_t;
-typedef int (*mu_m_server_conn_fp) (int fd, struct sockaddr *sa, int salen,
- void *data, mu_ip_server_t srv,
- time_t timeout, int transcript);
-typedef int (*mu_m_server_prefork_fp) (int, void *,
- struct sockaddr *s, int size);
+typedef int (*mu_m_server_handler_fp) (int fd, struct sockaddr *sa, int salen,
+ struct mu_srv_config *pconf,
+ void *data);
void mu_m_server_create (mu_m_server_t *psrv, const char *ident);
void mu_m_server_destroy (mu_m_server_t *pmsrv);
void mu_m_server_set_mode (mu_m_server_t srv, int mode);
void mu_m_server_set_type (mu_m_server_t srv, int type);
void mu_m_server_get_type (mu_m_server_t srv, int *ptype);
-void mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_conn_fp f);
-void mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_prefork_fp fun);
+void mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_handler_fp f);
+void mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_handler_fp fun);
void mu_m_server_set_data (mu_m_server_t srv, void *data);
void mu_m_server_set_max_children (mu_m_server_t srv, size_t num);
int mu_m_server_set_pidfile (mu_m_server_t srv, const char *pidfile);
@@ -103,6 +114,8 @@ void mu_m_server_set_timeout (mu_m_server_t srv, time_t t);
void mu_m_server_set_mode (mu_m_server_t srv, int mode);
void mu_m_server_set_sigset (mu_m_server_t srv, sigset_t *sigset);
void mu_m_server_set_strexit (mu_m_server_t srv, const char *(*fun) (int));
+void mu_m_server_set_app_data_size (mu_m_server_t srv, size_t size);
+int mu_m_server_set_config_size (mu_m_server_t srv, size_t size);
int mu_m_server_mode (mu_m_server_t srv);
int mu_m_server_foreground (mu_m_server_t srv);
@@ -120,7 +133,8 @@ void mu_m_server_end (mu_m_server_t msrv);
void mu_m_server_stop (int code);
int mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen);
-void mu_m_server_cfg_init (void);
+struct mu_cfg_param;
+void mu_m_server_cfg_init (struct mu_cfg_param *app_param);
#endif
diff --git a/include/mailutils/tls.h b/include/mailutils/tls.h
index 6fdd49af6..7fde4f9bd 100644
--- a/include/mailutils/tls.h
+++ b/include/mailutils/tls.h
@@ -49,7 +49,7 @@ extern int mu_tls_client_stream_create (mu_stream_t *stream,
int flags);
extern int mu_check_tls_environment (void);
-extern int mu_init_tls_libs (void);
+extern int mu_init_tls_libs (int x509);
extern void mu_deinit_tls_libs (void);
extern int mu_tls_enable;
diff --git a/lib/tcpwrap.c b/lib/tcpwrap.c
index 6b8d2ca8e..6c97a2388 100644
--- a/lib/tcpwrap.c
+++ b/lib/tcpwrap.c
@@ -27,9 +27,11 @@
#include <mailutils/cfg.h>
#include <mailutils/diag.h>
#include <mailutils/error.h>
+#include <mailutils/server.h>
+#include "tcpwrap.h"
int mu_tcp_wrapper_enable = 1;
-char *mu_tcp_wrapper_daemon;
+const char *mu_tcp_wrapper_daemon;
#ifdef WITH_LIBWRAP
# include <tcpd.h>
@@ -93,7 +95,9 @@ mu_tcpwrapper_access (int fd)
#endif
int
-mu_tcp_wrapper_prefork (int fd, void *data, struct sockaddr *sa, int salen)
+mu_tcp_wrapper_prefork (int fd, struct sockaddr *sa, int salen,
+ struct mu_srv_config *pconf,
+ void *data)
{
if (mu_tcp_wrapper_enable
&& sa->sa_family == AF_INET
diff --git a/lib/tcpwrap.h b/lib/tcpwrap.h
index 711bbb8a0..939889a38 100644
--- a/lib/tcpwrap.h
+++ b/lib/tcpwrap.h
@@ -21,8 +21,10 @@ extern int mu_tcp_wrapper_enable;
const char *mu_tcp_wrapper_daemon;
extern int mu_tcpwrapper_access (int fd);
extern void mu_tcpwrapper_cfg_init (void);
-extern int mu_tcp_wrapper_prefork (int fd, void *data,
- struct sockaddr *sa, int salen);
+extern int mu_tcp_wrapper_prefork (int fd,
+ struct sockaddr *sa, int salen,
+ struct mu_srv_config *pconf,
+ void *data);
#ifdef WITH_LIBWRAP
# define TCP_WRAPPERS_CONFIG { "tcp-wrappers", mu_cfg_section },
diff --git a/libmailutils/base/filesafety.c b/libmailutils/base/filesafety.c
index 6de1e9a77..ca075b479 100644
--- a/libmailutils/base/filesafety.c
+++ b/libmailutils/base/filesafety.c
@@ -195,7 +195,9 @@ mu_file_safety_check (const char *filename, int mode,
mu_list_t idlist)
{
struct file_check_buffer buf;
-
+
+ if (!filename)
+ return EFAULT;
memset (&buf, 0, sizeof (buf));
if (stat (filename, &buf.filst) == 0)
{
diff --git a/libmailutils/server/msrv.c b/libmailutils/server/msrv.c
index d5ceb8a39..fca9322c6 100644
--- a/libmailutils/server/msrv.c
+++ b/libmailutils/server/msrv.c
@@ -76,9 +76,10 @@ struct _mu_m_server
objects. It is cleared after the objects
are opened and attached to the server. */
- mu_m_server_conn_fp conn; /* Connection handler function. */
- mu_m_server_prefork_fp prefork;/* Pre-fork function. */
+ mu_m_server_handler_fp conn; /* Connection handler function. */
+ mu_m_server_handler_fp prefork;/* Pre-fork function. */
void *data; /* User-supplied data for conn and prefork. */
+ size_t app_data_size;
int mode; /* Server mode: should be removed. */
@@ -98,16 +99,6 @@ struct _mu_m_server
description. */
};
-struct m_srv_config /* Configuration data for a single TCP server. */
-{
- mu_m_server_t msrv; /* Parent m-server. */
- mu_ip_server_t tcpsrv; /* TCP server these data are for. */
- mu_acl_t acl; /* Access control list for this server. */
- int single_process; /* Should it run as a single process? */
- int transcript; /* Enable session transcript. */
- time_t timeout; /* Idle timeout for this server. */
-};
-
static int need_cleanup = 0;
static int stop = 0; /* FIXME: Must be per-m-server */
@@ -326,13 +317,13 @@ mu_m_server_set_mode (mu_m_server_t srv, int mode)
}
void
-mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_conn_fp conn)
+mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_handler_fp conn)
{
srv->conn = conn;
}
void
-mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_prefork_fp fun)
+mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_handler_fp fun)
{
srv->prefork = fun;
}
@@ -433,9 +424,24 @@ mu_m_server_foreground (mu_m_server_t srv)
}
void
-m_srv_config_free (void *data)
+mu_m_server_set_app_data_size (mu_m_server_t srv, size_t size)
+{
+ srv->app_data_size = size;
+}
+
+int
+mu_m_server_set_config_size (mu_m_server_t srv, size_t size)
+{
+ if (size < sizeof (struct mu_srv_config))
+ return EINVAL;
+ srv->app_data_size = size - sizeof (struct mu_srv_config);
+ return 0;
+}
+
+void
+mu_srv_config_free (void *data)
{
- struct m_srv_config *pconf = data;
+ struct mu_srv_config *pconf = data;
/* FIXME */
free (pconf);
}
@@ -444,15 +450,15 @@ static int m_srv_conn (int fd, struct sockaddr *sa, int salen,
void *server_data, void *call_data,
mu_ip_server_t srv);
-static struct m_srv_config *
+static struct mu_srv_config *
add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type)
{
mu_ip_server_t tcpsrv;
- struct m_srv_config *pconf;
+ struct mu_srv_config *pconf;
MU_ASSERT (mu_ip_server_create (&tcpsrv, s, type)); /* FIXME: type */
MU_ASSERT (mu_ip_server_set_conn (tcpsrv, m_srv_conn));
- pconf = calloc (1, sizeof (*pconf));
+ pconf = calloc (1, sizeof (*pconf) + msrv->app_data_size);
if (!pconf)
{
mu_error ("%s", mu_strerror (ENOMEM));
@@ -462,7 +468,7 @@ add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type)
pconf->tcpsrv = tcpsrv;
pconf->single_process = 0;
pconf->timeout = msrv->timeout;
- MU_ASSERT (mu_ip_server_set_data (tcpsrv, pconf, m_srv_config_free));
+ MU_ASSERT (mu_ip_server_set_data (tcpsrv, pconf, mu_srv_config_free));
if (!msrv->srvlist)
MU_ASSERT (mu_list_create (&msrv->srvlist));
MU_ASSERT (mu_list_append (msrv->srvlist, tcpsrv));
@@ -681,7 +687,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
mu_ip_server_t srv)
{
int status;
- struct m_srv_config *pconf = server_data;
+ struct mu_srv_config *pconf = server_data;
if (mu_m_server_check_acl (pconf->msrv, sa, salen))
return 0;
@@ -701,7 +707,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
return 0;
}
if (pconf->msrv->prefork
- && pconf->msrv->prefork (fd, pconf->msrv->data, sa, salen))
+ && pconf->msrv->prefork (fd, sa, salen, pconf, pconf->msrv->data))
return 0;
pid = fork ();
@@ -711,8 +717,8 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
{
mu_ip_server_shutdown (srv); /* FIXME: does it harm for MU_IP_UDP? */
mu_m_server_restore_signals (pconf->msrv);
- status = pconf->msrv->conn (fd, sa, salen, pconf->msrv->data, srv,
- pconf->timeout, pconf->transcript);
+ status = pconf->msrv->conn (fd, sa, salen, pconf,
+ pconf->msrv->data);
closelog ();
exit (status);
}
@@ -722,9 +728,9 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
}
}
else if (!pconf->msrv->prefork
- || pconf->msrv->prefork (fd, pconf->msrv->data, sa, salen) == 0)
- pconf->msrv->conn (fd, sa, salen, pconf->msrv->data, srv,
- pconf->timeout, pconf->transcript);
+ || pconf->msrv->prefork (fd, sa, salen, pconf,
+ pconf->msrv->data) == 0)
+ pconf->msrv->conn (fd, sa, salen, pconf, pconf->msrv->data);
return 0;
}
@@ -802,7 +808,7 @@ server_section_parser (enum mu_cfg_section_stage stage,
case mu_cfg_section_end:
{
- struct m_srv_config *pconf = *section_data;
+ struct mu_srv_config *pconf = *section_data;
if (pconf->acl)
mu_ip_server_set_acl (pconf->tcpsrv, pconf->acl);
}
@@ -904,22 +910,22 @@ static struct mu_cfg_param dot_server_cfg_param[] = {
static struct mu_cfg_param server_cfg_param[] = {
{ "single-process", mu_cfg_bool,
- NULL, mu_offsetof (struct m_srv_config, single_process), NULL,
+ NULL, mu_offsetof (struct mu_srv_config, single_process), NULL,
N_("Run this server in foreground.") },
{ "transcript", mu_cfg_bool,
- NULL, mu_offsetof (struct m_srv_config, transcript), NULL,
+ NULL, mu_offsetof (struct mu_srv_config, transcript), NULL,
N_("Log the session transcript.") },
{ "timeout", mu_cfg_time,
- NULL, mu_offsetof (struct m_srv_config, timeout), NULL,
+ NULL, mu_offsetof (struct mu_srv_config, timeout), NULL,
N_("Set idle timeout.") },
{ "acl", mu_cfg_section,
- NULL, mu_offsetof (struct m_srv_config, acl), NULL,
+ NULL, mu_offsetof (struct mu_srv_config, acl), NULL,
N_("Global access control list.") },
{ NULL }
};
void
-mu_m_server_cfg_init ()
+mu_m_server_cfg_init (struct mu_cfg_param *app_param)
{
struct mu_cfg_section *section;
if (mu_create_canned_section ("server", &section) == 0)
@@ -927,6 +933,8 @@ mu_m_server_cfg_init ()
section->parser = server_section_parser;
section->label = N_("ipaddr[:port]");
mu_cfg_section_add_params (section, server_cfg_param);
+ if (app_param)
+ mu_cfg_section_add_params (section, app_param);
}
if (mu_create_canned_section (".server", &section) == 0)
{
diff --git a/libmu_auth/tls.c b/libmu_auth/tls.c
index 054fb921a..ef8df9302 100644
--- a/libmu_auth/tls.c
+++ b/libmu_auth/tls.c
@@ -55,7 +55,7 @@ mu_tls_module_init (enum mu_gocs_op op, void *data)
case mu_gocs_op_flush:
#ifdef WITH_TLS
- mu_init_tls_libs ();
+ mu_init_tls_libs (0);
#endif
break;
}
@@ -99,14 +99,17 @@ mu_check_tls_environment (void)
return 0;
}
- rc = mu_file_safety_check (mu_tls_module_config.ssl_cafile,
- mu_tls_module_config.ssl_cafile_safety_checks,
- -1, NULL);
- if (rc)
+ if (mu_tls_module_config.ssl_cafile)
{
- mu_error ("%s: %s", mu_tls_module_config.ssl_cafile,
- mu_strerror (rc));
- return 0;
+ rc = mu_file_safety_check (mu_tls_module_config.ssl_cafile,
+ mu_tls_module_config.ssl_cafile_safety_checks,
+ -1, NULL);
+ if (rc)
+ {
+ mu_error ("%s: %s", mu_tls_module_config.ssl_cafile,
+ mu_strerror (rc));
+ return 0;
+ }
}
}
else
@@ -126,10 +129,40 @@ _mu_gtls_logger(int level, const char *text)
#endif
int
-mu_init_tls_libs (void)
+mu_init_tls_libs (int x509_setup)
{
if (!mu_tls_enable)
- mu_tls_enable = !gnutls_global_init (); /* Returns 1 on success */
+ {
+ int rc;
+ if ((rc = gnutls_global_init ()) == GNUTLS_E_SUCCESS)
+ mu_tls_enable = 1;
+ else
+ {
+ mu_error ("gnutls_global_init: %s", gnutls_strerror (rc));
+ return 0;
+ }
+ }
+
+ if (x509_setup && !x509_cred)
+ {
+ mu_diag_output (MU_DIAG_INFO, _("initializing X509..."));
+ gnutls_certificate_allocate_credentials (&x509_cred);
+ if (mu_tls_module_config.ssl_cafile)
+ gnutls_certificate_set_x509_trust_file (x509_cred,
+ mu_tls_module_config.ssl_cafile,
+ GNUTLS_X509_FMT_PEM);
+
+ gnutls_certificate_set_x509_key_file (x509_cred,
+ mu_tls_module_config.ssl_cert,
+ mu_tls_module_config.ssl_key,
+ GNUTLS_X509_FMT_PEM);
+
+ gnutls_dh_params_init (&dh_params);
+ gnutls_dh_params_generate2 (dh_params, DH_BITS);
+ gnutls_certificate_set_dh_params (x509_cred, dh_params);
+ mu_diag_output (MU_DIAG_INFO, _("finished initializing X509"));
+ }
+
#ifdef DEBUG_TLS
gnutls_global_set_log_function (_mu_gtls_logger);
gnutls_global_set_log_level (110);
@@ -141,17 +174,14 @@ void
mu_deinit_tls_libs (void)
{
if (mu_tls_enable)
- gnutls_global_deinit ();
+ {
+ if (x509_cred)
+ gnutls_certificate_free_credentials (x509_cred);
+ gnutls_global_deinit ();
+ }
mu_tls_enable = 0;
}
-static void
-generate_dh_params (void)
-{
- gnutls_dh_params_init (&dh_params);
- gnutls_dh_params_generate2 (dh_params, DH_BITS);
-}
-
static gnutls_session
initialize_tls_session (void)
{
@@ -382,28 +412,8 @@ _tls_server_open (mu_stream_t stream)
if (!stream || sp->state != state_init)
return EINVAL;
- mu_init_tls_libs ();
+ mu_init_tls_libs (1);
- gnutls_certificate_allocate_credentials (&x509_cred);
-
- if (mu_tls_module_config.ssl_cafile)
- gnutls_certificate_set_x509_trust_file (x509_cred,
- mu_tls_module_config.ssl_cafile,
- GNUTLS_X509_FMT_PEM);
-
- rc = gnutls_certificate_set_x509_key_file (x509_cred,
- mu_tls_module_config.ssl_cert,
- mu_tls_module_config.ssl_key,
- GNUTLS_X509_FMT_PEM);
- if (rc < 0)
- {
- sp->tls_err = rc;
- return EIO;
- }
-
- generate_dh_params ();
- gnutls_certificate_set_dh_params (x509_cred, dh_params);
-
sp->session = initialize_tls_session ();
mu_stream_ioctl (stream, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, transport);
gnutls_transport_set_ptr2 (sp->session,
@@ -478,13 +488,12 @@ _tls_client_open (mu_stream_t stream)
switch (sp->state)
{
case state_closed:
- gnutls_certificate_free_credentials (x509_cred);
if (sp->session)
gnutls_deinit (sp->session);
/* FALLTHROUGH */
case state_init:
- mu_init_tls_libs ();
+ mu_init_tls_libs (0);
prepare_client_session (stream);
rc = gnutls_handshake (sp->session);
if (rc < 0)
@@ -630,8 +639,6 @@ _tls_done (struct _mu_stream *stream)
{
struct _mu_tls_stream *sp = (struct _mu_tls_stream *) stream;
- if (x509_cred)
- gnutls_certificate_free_credentials (x509_cred);
if (sp->session && sp->state == state_closed)
{
gnutls_deinit (sp->session);
diff --git a/libmu_cfg/tls.c b/libmu_cfg/tls.c
index d65918911..8bcc518f5 100644
--- a/libmu_cfg/tls.c
+++ b/libmu_cfg/tls.c
@@ -52,11 +52,11 @@ cb2_safety_checks (const char *name, void *data)
{
int defval;
- if (data == &tls_settings.ssl_key)
+ if (data == &tls_settings.ssl_key_safety_checks)
defval = SSL_KEY_FILE_CHECKS;
- else if (data == &tls_settings.ssl_cert)
+ else if (data == &tls_settings.ssl_cert_safety_checks)
defval = SSL_CERT_FILE_CHECKS;
- else if (data == &tls_settings.ssl_cafile)
+ else if (data == &tls_settings.ssl_cafile_safety_checks)
defval = SSL_CA_FILE_CHECKS;
else
{
diff --git a/maidag/lmtp.c b/maidag/lmtp.c
index f493b6766..12f4214b8 100644
--- a/maidag/lmtp.c
+++ b/maidag/lmtp.c
@@ -574,8 +574,9 @@ typedef union
} all_addr_t;
int
-lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data,
- mu_ip_server_t srv, time_t timeout, int transcript)
+lmtp_connection (int fd, struct sockaddr *sa, int salen,
+ struct mu_srv_config *pconf,
+ void *data)
{
mu_stream_t str;
int rc;
@@ -588,9 +589,9 @@ lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data,
}
mu_stream_set_buffer (str, mu_buffer_line, 0);
- if (transcript || maidag_transcript)
+ if (pconf->transcript || maidag_transcript)
str = lmtp_transcript (str);
- lmtp_loop (str, timeout);
+ lmtp_loop (str, pconf->timeout);
mu_stream_destroy (&str);
return 0;
}
diff --git a/maidag/maidag.c b/maidag/maidag.c
index eee6d83b6..decbe91f4 100644
--- a/maidag/maidag.c
+++ b/maidag/maidag.c
@@ -525,7 +525,7 @@ main (int argc, char *argv[])
mu_tcpwrapper_cfg_init ();
mu_acl_cfg_init ();
- mu_m_server_cfg_init ();
+ mu_m_server_cfg_init (NULL);
maidag_cfg_init ();
/* Parse command line */
diff --git a/maidag/maidag.h b/maidag/maidag.h
index 5125fe7a9..1c59b191a 100644
--- a/maidag/maidag.h
+++ b/maidag/maidag.h
@@ -150,8 +150,9 @@ int deliver_to_user (mu_message_t msg, char *dest_id, char **errp);
int maidag_stdio_delivery (maidag_delivery_fn fun, int argc, char **argv);
int maidag_lmtp_server (void);
-int lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data,
- mu_ip_server_t srv, time_t timeout, int transcript);
+int lmtp_connection (int fd, struct sockaddr *sa, int salen,
+ struct mu_srv_config *pconf,
+ void *data);
void maidag_error (const char *fmt, ...) MU_PRINTFLIKE(1, 2);
void notify_biff (mu_mailbox_t mbox, char *name, size_t size);
diff --git a/pop3d/extra.c b/pop3d/extra.c
index c2d1c420f..83f468a45 100644
--- a/pop3d/extra.c
+++ b/pop3d/extra.c
@@ -93,6 +93,10 @@ pop3d_abquit (int reason)
mu_diag_output (MU_DIAG_INFO, _("no socket to send to"));
break;
+ case ERR_FILE:
+ code = EX_IOERR;
+ break;
+
case ERR_PROTO:
code = EX_PROTOCOL;
mu_diag_output (MU_DIAG_INFO, _("remote protocol error"));
@@ -125,7 +129,7 @@ pop3d_abquit (int reason)
}
void
-pop3d_setio (int ifd, int ofd)
+pop3d_setio (int ifd, int ofd, int tls)
{
mu_stream_t str, istream, ostream;
@@ -137,11 +141,26 @@ pop3d_setio (int ifd, int ofd)
if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ))
pop3d_abquit (ERR_NO_IFILE);
mu_stream_set_buffer (istream, mu_buffer_line, 0);
-
+
if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE))
pop3d_abquit (ERR_NO_OFILE);
/* Combine the two streams into an I/O one. */
+#ifdef WITH_TLS
+ if (tls)
+ {
+ int rc = mu_tls_server_stream_create (&str, istream, ostream, 0);
+ if (rc)
+ {
+ mu_stream_unref (istream);<