diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-04 21:30:38 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-04 21:44:56 +0200 |
commit | e1233d5516f48cd7d786a69d4eebd40e73d95d45 (patch) | |
tree | 38692d813e645ac60bfababee4c5f7ec7f8cede9 | |
parent | bad3c6c3a982f65af0fe137d1e5b7a98d13bb9d5 (diff) | |
download | mailutils-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.c | 16 | ||||
-rw-r--r-- | imap4d/imap4d.c | 38 | ||||
-rw-r--r-- | imap4d/imap4d.h | 3 | ||||
-rw-r--r-- | imap4d/io.c | 17 | ||||
-rw-r--r-- | imap4d/starttls.c | 28 | ||||
-rw-r--r-- | include/mailutils/server.h | 30 | ||||
-rw-r--r-- | include/mailutils/tls.h | 2 | ||||
-rw-r--r-- | lib/tcpwrap.c | 8 | ||||
-rw-r--r-- | lib/tcpwrap.h | 6 | ||||
-rw-r--r-- | libmailutils/base/filesafety.c | 4 | ||||
-rw-r--r-- | libmailutils/server/msrv.c | 74 | ||||
-rw-r--r-- | libmu_auth/tls.c | 93 | ||||
-rw-r--r-- | libmu_cfg/tls.c | 6 | ||||
-rw-r--r-- | maidag/lmtp.c | 9 | ||||
-rw-r--r-- | maidag/maidag.c | 2 | ||||
-rw-r--r-- | maidag/maidag.h | 5 | ||||
-rw-r--r-- | pop3d/extra.c | 23 | ||||
-rw-r--r-- | pop3d/pop3d.c | 43 | ||||
-rw-r--r-- | pop3d/pop3d.h | 2 |
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", §ion) == 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", §ion) == 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);< |