Commit e1233d55 e1233d5516f48cd7d786a69d4eebd40e73d95d45 by Sergey Poznyakoff

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.
1 parent bad3c6c3
...@@ -320,7 +320,8 @@ static unsigned overflow_count = 0; /* Number of overflows detected during ...@@ -320,7 +320,8 @@ static unsigned overflow_count = 0; /* Number of overflows detected during
320 the current interval */ 320 the current interval */
321 321
322 int 322 int
323 comsat_prefork (int fd, void *data, struct sockaddr *s, int size) 323 comsat_prefork (int fd, struct sockaddr *s, int size,
324 struct mu_srv_config *pconf, void *data)
324 { 325 {
325 int retval = 0; 326 int retval = 0;
326 time_t now; 327 time_t now;
...@@ -367,15 +368,14 @@ comsat_prefork (int fd, void *data, struct sockaddr *s, int size) ...@@ -367,15 +368,14 @@ comsat_prefork (int fd, void *data, struct sockaddr *s, int size)
367 368
368 int 369 int
369 comsat_connection (int fd, struct sockaddr *sa, int salen, 370 comsat_connection (int fd, struct sockaddr *sa, int salen,
370 void *data, mu_ip_server_t srv, 371 struct mu_srv_config *pconf, void *data)
371 time_t to, int transcript)
372 { 372 {
373 char *buffer; 373 char *buffer;
374 size_t rdlen, size; 374 size_t rdlen, size;
375 375
376 if (mu_udp_server_get_rdata (srv, &buffer, &rdlen)) 376 if (mu_udp_server_get_rdata (pconf->tcpsrv, &buffer, &rdlen))
377 return 0; 377 return 0;
378 if (transcript) 378 if (pconf->transcript)
379 { 379 {
380 char *p = mu_sockaddr_to_astr (sa, salen); 380 char *p = mu_sockaddr_to_astr (sa, salen);
381 mu_diag_output (MU_DIAG_INFO, 381 mu_diag_output (MU_DIAG_INFO,
...@@ -386,10 +386,10 @@ comsat_connection (int fd, struct sockaddr *sa, int salen, ...@@ -386,10 +386,10 @@ comsat_connection (int fd, struct sockaddr *sa, int salen,
386 mu_diag_output (MU_DIAG_INFO, "string: %s", buffer); 386 mu_diag_output (MU_DIAG_INFO, "string: %s", buffer);
387 free (p); 387 free (p);
388 } 388 }
389 mu_udp_server_get_bufsize (srv, &size); 389 mu_udp_server_get_bufsize (pconf->tcpsrv, &size);
390 if (size < rdlen + 1) 390 if (size < rdlen + 1)
391 { 391 {
392 int rc = mu_udp_server_set_bufsize (srv, rdlen + 1); 392 int rc = mu_udp_server_set_bufsize (pconf->tcpsrv, rdlen + 1);
393 if (rc) 393 if (rc)
394 { 394 {
395 mu_error (_("cannot resize buffer: %s"), mu_strerror (rc)); 395 mu_error (_("cannot resize buffer: %s"), mu_strerror (rc));
...@@ -560,7 +560,7 @@ main (int argc, char **argv) ...@@ -560,7 +560,7 @@ main (int argc, char **argv)
560 mu_argp_init (NULL, NULL); 560 mu_argp_init (NULL, NULL);
561 comsat_init (); 561 comsat_init ();
562 mu_acl_cfg_init (); 562 mu_acl_cfg_init ();
563 mu_m_server_cfg_init (); 563 mu_m_server_cfg_init (NULL);
564 mu_m_server_create (&server, program_version); 564 mu_m_server_create (&server, program_version);
565 mu_m_server_set_type (server, MU_IP_UDP); 565 mu_m_server_set_type (server, MU_IP_UDP);
566 mu_m_server_set_conn (server, comsat_connection); 566 mu_m_server_set_conn (server, comsat_connection);
......
...@@ -93,7 +93,7 @@ static const char *imap4d_capa[] = { ...@@ -93,7 +93,7 @@ static const char *imap4d_capa[] = {
93 NULL 93 NULL
94 }; 94 };
95 95
96 static int imap4d_mainloop (int, int); 96 static int imap4d_mainloop (int, int, int);
97 97
98 static error_t 98 static error_t
99 imap4d_parse_opt (int key, char *arg, struct argp_state *state) 99 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) ...@@ -242,6 +242,20 @@ cb_mailbox_mode (void *data, mu_config_value_t *val)
242 return 0; 242 return 0;
243 } 243 }
244 244
245 struct imap4d_srv_config
246 {
247 struct mu_srv_config m_cfg;
248 int tls;
249 };
250
251 static struct mu_cfg_param imap4d_srv_param[] = {
252 { "tls", mu_cfg_bool, NULL, mu_offsetof (struct imap4d_srv_config, tls),
253 NULL,
254 N_("Use TLS encryption for this server")
255 },
256 { NULL }
257 };
258
245 static struct mu_cfg_param imap4d_cfg_param[] = { 259 static struct mu_cfg_param imap4d_cfg_param[] = {
246 { "homedir", mu_cfg_string, &modify_homedir, 0, NULL, 260 { "homedir", mu_cfg_string, &modify_homedir, 0, NULL,
247 N_("Modify home directory.") }, 261 N_("Modify home directory.") },
...@@ -396,7 +410,7 @@ imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo)) ...@@ -396,7 +410,7 @@ imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
396 } 410 }
397 411
398 static int 412 static int
399 imap4d_mainloop (int ifd, int ofd) 413 imap4d_mainloop (int ifd, int ofd, int tls)
400 { 414 {
401 imap4d_tokbuf_t tokp; 415 imap4d_tokbuf_t tokp;
402 char *text; 416 char *text;
...@@ -435,7 +449,7 @@ imap4d_mainloop (int ifd, int ofd) ...@@ -435,7 +449,7 @@ imap4d_mainloop (int ifd, int ofd)
435 imap4d_child_signal_setup (imap4d_child_signal); 449 imap4d_child_signal_setup (imap4d_child_signal);
436 } 450 }
437 451
438 io_setio (ifd, ofd); 452 io_setio (ifd, ofd, tls);
439 453
440 if (imap4d_preauth_setup (ifd) == 0) 454 if (imap4d_preauth_setup (ifd) == 0)
441 { 455 {
...@@ -478,13 +492,14 @@ imap4d_mainloop (int ifd, int ofd) ...@@ -478,13 +492,14 @@ imap4d_mainloop (int ifd, int ofd)
478 } 492 }
479 493
480 int 494 int
481 imap4d_connection (int fd, struct sockaddr *sa, int salen, void *data, 495 imap4d_connection (int fd, struct sockaddr *sa, int salen,
482 mu_ip_server_t srv, time_t timeout, int transcript) 496 struct mu_srv_config *pconf, void *data)
483 { 497 {
484 idle_timeout = timeout; 498 struct imap4d_srv_config *cfg = (struct imap4d_srv_config *) pconf;
485 if (imap4d_transcript != transcript) 499
486 imap4d_transcript = transcript; 500 idle_timeout = pconf->timeout;
487 imap4d_mainloop (fd, fd); 501 imap4d_transcript = pconf->transcript;
502 imap4d_mainloop (fd, fd, cfg->tls);
488 return 0; 503 return 0;
489 } 504 }
490 505
...@@ -559,11 +574,12 @@ main (int argc, char **argv) ...@@ -559,11 +574,12 @@ main (int argc, char **argv)
559 mu_tcpwrapper_cfg_init (); 574 mu_tcpwrapper_cfg_init ();
560 manlock_cfg_init (); 575 manlock_cfg_init ();
561 mu_acl_cfg_init (); 576 mu_acl_cfg_init ();
562 mu_m_server_cfg_init (); 577 mu_m_server_cfg_init (imap4d_srv_param);
563 578
564 mu_argp_init (NULL, NULL); 579 mu_argp_init (NULL, NULL);
565 580
566 mu_m_server_create (&server, program_version); 581 mu_m_server_create (&server, program_version);
582 mu_m_server_set_config_size (server, sizeof (struct imap4d_srv_config));
567 mu_m_server_set_conn (server, imap4d_connection); 583 mu_m_server_set_conn (server, imap4d_connection);
568 mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork); 584 mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork);
569 mu_m_server_set_mode (server, MODE_INTERACTIVE); 585 mu_m_server_set_mode (server, MODE_INTERACTIVE);
...@@ -669,7 +685,7 @@ main (int argc, char **argv) ...@@ -669,7 +685,7 @@ main (int argc, char **argv)
669 { 685 {
670 /* Make sure we are in the root directory. */ 686 /* Make sure we are in the root directory. */
671 chdir ("/"); 687 chdir ("/");
672 status = imap4d_mainloop (MU_STDIN_FD, MU_STDOUT_FD); 688 status = imap4d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, 0);
673 } 689 }
674 690
675 if (status) 691 if (status)
......
...@@ -220,7 +220,7 @@ extern int io_stream_completion_response (mu_stream_t str, ...@@ -220,7 +220,7 @@ extern int io_stream_completion_response (mu_stream_t str,
220 const char *format, ...) 220 const char *format, ...)
221 MU_PRINTFLIKE(4,5); 221 MU_PRINTFLIKE(4,5);
222 void io_getline (char **pbuf, size_t *psize, size_t *pnbytes); 222 void io_getline (char **pbuf, size_t *psize, size_t *pnbytes);
223 void io_setio (int, int); 223 void io_setio (int, int, int);
224 void io_flush (void); 224 void io_flush (void);
225 int io_wait_input (int); 225 int io_wait_input (int);
226 226
...@@ -297,6 +297,7 @@ extern int imap4d_select_status (void); ...@@ -297,6 +297,7 @@ extern int imap4d_select_status (void);
297 #ifdef WITH_TLS 297 #ifdef WITH_TLS
298 extern int imap4d_starttls (struct imap4d_command *, imap4d_tokbuf_t); 298 extern int imap4d_starttls (struct imap4d_command *, imap4d_tokbuf_t);
299 extern void starttls_init (void); 299 extern void starttls_init (void);
300 void tls_encryption_on (void);
300 #endif /* WITH_TLS */ 301 #endif /* WITH_TLS */
301 extern int imap4d_status (struct imap4d_command *, imap4d_tokbuf_t); 302 extern int imap4d_status (struct imap4d_command *, imap4d_tokbuf_t);
302 extern int imap4d_store (struct imap4d_command *, imap4d_tokbuf_t); 303 extern int imap4d_store (struct imap4d_command *, imap4d_tokbuf_t);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 mu_stream_t iostream; 20 mu_stream_t iostream;
21 21
22 void 22 void
23 io_setio (int ifd, int ofd) 23 io_setio (int ifd, int ofd, int tls)
24 { 24 {
25 mu_stream_t str, istream, ostream; 25 mu_stream_t str, istream, ostream;
26 26
...@@ -38,6 +38,21 @@ io_setio (int ifd, int ofd) ...@@ -38,6 +38,21 @@ io_setio (int ifd, int ofd)
38 mu_stream_set_buffer (ostream, mu_buffer_line, 0); 38 mu_stream_set_buffer (ostream, mu_buffer_line, 0);
39 39
40 /* Combine the two streams into an I/O one. */ 40 /* Combine the two streams into an I/O one. */
41 #ifdef WITH_TLS
42 if (tls)
43 {
44 int rc = mu_tls_server_stream_create (&str, istream, ostream, 0);
45 if (rc)
46 {
47 mu_stream_unref (istream);
48 mu_stream_unref (ostream);
49 mu_error (_("failed to create TLS stream: %s"), mu_strerror (rc));
50 imap4d_bye (ERR_STREAM_CREATE);
51 }
52 tls_encryption_on ();
53 }
54 else
55 #endif
41 if (mu_iostream_create (&str, istream, ostream)) 56 if (mu_iostream_create (&str, istream, ostream))
42 imap4d_bye (ERR_STREAM_CREATE); 57 imap4d_bye (ERR_STREAM_CREATE);
43 58
......
...@@ -47,18 +47,9 @@ imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -47,18 +47,9 @@ imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok)
47 47
48 status = io_completion_response (command, RESP_OK, "Begin TLS negotiation"); 48 status = io_completion_response (command, RESP_OK, "Begin TLS negotiation");
49 io_flush (); 49 io_flush ();
50 tls_done = imap4d_init_tls_server () == 0;
51 50
52 if (tls_done) 51 if (imap4d_init_tls_server () == 0)
53 { 52 tls_encryption_on ();
54 imap4d_capability_remove (IMAP_CAPA_STARTTLS);
55
56 login_disabled = 0;
57 imap4d_capability_remove (IMAP_CAPA_LOGINDISABLED);
58
59 tls_required = 0;
60 imap4d_capability_remove (IMAP_CAPA_XTLSREQUIRED);
61 }
62 else 53 else
63 { 54 {
64 mu_diag_output (MU_DIAG_ERROR, _("session terminated")); 55 mu_diag_output (MU_DIAG_ERROR, _("session terminated"));
...@@ -70,11 +61,24 @@ imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok) ...@@ -70,11 +61,24 @@ imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok)
70 } 61 }
71 62
72 void 63 void
64 tls_encryption_on ()
65 {
66 tls_done = 1;
67 imap4d_capability_remove (IMAP_CAPA_STARTTLS);
68
69 login_disabled = 0;
70 imap4d_capability_remove (IMAP_CAPA_LOGINDISABLED);
71
72 tls_required = 0;
73 imap4d_capability_remove (IMAP_CAPA_XTLSREQUIRED);
74 }
75
76 void
73 starttls_init () 77 starttls_init ()
74 { 78 {
75 tls_available = mu_check_tls_environment (); 79 tls_available = mu_check_tls_environment ();
76 if (tls_available) 80 if (tls_available)
77 tls_available = mu_init_tls_libs (); 81 tls_available = mu_init_tls_libs (1);
78 if (tls_available) 82 if (tls_available)
79 imap4d_capability_add (IMAP_CAPA_STARTTLS); 83 imap4d_capability_add (IMAP_CAPA_STARTTLS);
80 } 84 }
......
...@@ -80,20 +80,31 @@ int mu_udp_server_get_rdata (mu_ip_server_t srv, char **pbuf, ...@@ -80,20 +80,31 @@ int mu_udp_server_get_rdata (mu_ip_server_t srv, char **pbuf,
80 80
81 81
82 /* m-server */ 82 /* m-server */
83
84 struct mu_srv_config /* Configuration data for a single TCP server. */
85 {
86 mu_m_server_t msrv; /* Parent m-server. */
87 mu_ip_server_t tcpsrv; /* TCP server these data are for. */
88 mu_acl_t acl; /* Access control list for this server. */
89 int single_process; /* Should it run as a single process? */
90 int transcript; /* Enable session transcript. */
91 time_t timeout; /* Idle timeout for this server. */
92 /* Application-dependent data may follow */
93 };
94
95
83 typedef struct mu_m_server_connect_data mu_m_server_connect_data_t; 96 typedef struct mu_m_server_connect_data mu_m_server_connect_data_t;
84 typedef int (*mu_m_server_conn_fp) (int fd, struct sockaddr *sa, int salen, 97 typedef int (*mu_m_server_handler_fp) (int fd, struct sockaddr *sa, int salen,
85 void *data, mu_ip_server_t srv, 98 struct mu_srv_config *pconf,
86 time_t timeout, int transcript); 99 void *data);
87 typedef int (*mu_m_server_prefork_fp) (int, void *,
88 struct sockaddr *s, int size);
89 100
90 void mu_m_server_create (mu_m_server_t *psrv, const char *ident); 101 void mu_m_server_create (mu_m_server_t *psrv, const char *ident);
91 void mu_m_server_destroy (mu_m_server_t *pmsrv); 102 void mu_m_server_destroy (mu_m_server_t *pmsrv);
92 void mu_m_server_set_mode (mu_m_server_t srv, int mode); 103 void mu_m_server_set_mode (mu_m_server_t srv, int mode);
93 void mu_m_server_set_type (mu_m_server_t srv, int type); 104 void mu_m_server_set_type (mu_m_server_t srv, int type);
94 void mu_m_server_get_type (mu_m_server_t srv, int *ptype); 105 void mu_m_server_get_type (mu_m_server_t srv, int *ptype);
95 void mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_conn_fp f); 106 void mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_handler_fp f);
96 void mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_prefork_fp fun); 107 void mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_handler_fp fun);
97 void mu_m_server_set_data (mu_m_server_t srv, void *data); 108 void mu_m_server_set_data (mu_m_server_t srv, void *data);
98 void mu_m_server_set_max_children (mu_m_server_t srv, size_t num); 109 void mu_m_server_set_max_children (mu_m_server_t srv, size_t num);
99 int mu_m_server_set_pidfile (mu_m_server_t srv, const char *pidfile); 110 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); ...@@ -103,6 +114,8 @@ void mu_m_server_set_timeout (mu_m_server_t srv, time_t t);
103 void mu_m_server_set_mode (mu_m_server_t srv, int mode); 114 void mu_m_server_set_mode (mu_m_server_t srv, int mode);
104 void mu_m_server_set_sigset (mu_m_server_t srv, sigset_t *sigset); 115 void mu_m_server_set_sigset (mu_m_server_t srv, sigset_t *sigset);
105 void mu_m_server_set_strexit (mu_m_server_t srv, const char *(*fun) (int)); 116 void mu_m_server_set_strexit (mu_m_server_t srv, const char *(*fun) (int));
117 void mu_m_server_set_app_data_size (mu_m_server_t srv, size_t size);
118 int mu_m_server_set_config_size (mu_m_server_t srv, size_t size);
106 119
107 int mu_m_server_mode (mu_m_server_t srv); 120 int mu_m_server_mode (mu_m_server_t srv);
108 int mu_m_server_foreground (mu_m_server_t srv); 121 int mu_m_server_foreground (mu_m_server_t srv);
...@@ -120,7 +133,8 @@ void mu_m_server_end (mu_m_server_t msrv); ...@@ -120,7 +133,8 @@ void mu_m_server_end (mu_m_server_t msrv);
120 void mu_m_server_stop (int code); 133 void mu_m_server_stop (int code);
121 int mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen); 134 int mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen);
122 135
123 void mu_m_server_cfg_init (void); 136 struct mu_cfg_param;
137 void mu_m_server_cfg_init (struct mu_cfg_param *app_param);
124 138
125 139
126 #endif 140 #endif
......
...@@ -49,7 +49,7 @@ extern int mu_tls_client_stream_create (mu_stream_t *stream, ...@@ -49,7 +49,7 @@ extern int mu_tls_client_stream_create (mu_stream_t *stream,
49 int flags); 49 int flags);
50 50
51 extern int mu_check_tls_environment (void); 51 extern int mu_check_tls_environment (void);
52 extern int mu_init_tls_libs (void); 52 extern int mu_init_tls_libs (int x509);
53 extern void mu_deinit_tls_libs (void); 53 extern void mu_deinit_tls_libs (void);
54 54
55 extern int mu_tls_enable; 55 extern int mu_tls_enable;
......
...@@ -27,9 +27,11 @@ ...@@ -27,9 +27,11 @@
27 #include <mailutils/cfg.h> 27 #include <mailutils/cfg.h>
28 #include <mailutils/diag.h> 28 #include <mailutils/diag.h>
29 #include <mailutils/error.h> 29 #include <mailutils/error.h>
30 #include <mailutils/server.h>
31 #include "tcpwrap.h"
30 32
31 int mu_tcp_wrapper_enable = 1; 33 int mu_tcp_wrapper_enable = 1;
32 char *mu_tcp_wrapper_daemon; 34 const char *mu_tcp_wrapper_daemon;
33 35
34 #ifdef WITH_LIBWRAP 36 #ifdef WITH_LIBWRAP
35 # include <tcpd.h> 37 # include <tcpd.h>
...@@ -93,7 +95,9 @@ mu_tcpwrapper_access (int fd) ...@@ -93,7 +95,9 @@ mu_tcpwrapper_access (int fd)
93 #endif 95 #endif
94 96
95 int 97 int
96 mu_tcp_wrapper_prefork (int fd, void *data, struct sockaddr *sa, int salen) 98 mu_tcp_wrapper_prefork (int fd, struct sockaddr *sa, int salen,
99 struct mu_srv_config *pconf,
100 void *data)
97 { 101 {
98 if (mu_tcp_wrapper_enable 102 if (mu_tcp_wrapper_enable
99 && sa->sa_family == AF_INET 103 && sa->sa_family == AF_INET
......
...@@ -21,8 +21,10 @@ extern int mu_tcp_wrapper_enable; ...@@ -21,8 +21,10 @@ extern int mu_tcp_wrapper_enable;
21 const char *mu_tcp_wrapper_daemon; 21 const char *mu_tcp_wrapper_daemon;
22 extern int mu_tcpwrapper_access (int fd); 22 extern int mu_tcpwrapper_access (int fd);
23 extern void mu_tcpwrapper_cfg_init (void); 23 extern void mu_tcpwrapper_cfg_init (void);
24 extern int mu_tcp_wrapper_prefork (int fd, void *data, 24 extern int mu_tcp_wrapper_prefork (int fd,
25 struct sockaddr *sa, int salen); 25 struct sockaddr *sa, int salen,
26 struct mu_srv_config *pconf,
27 void *data);
26 28
27 #ifdef WITH_LIBWRAP 29 #ifdef WITH_LIBWRAP
28 # define TCP_WRAPPERS_CONFIG { "tcp-wrappers", mu_cfg_section }, 30 # define TCP_WRAPPERS_CONFIG { "tcp-wrappers", mu_cfg_section },
......
...@@ -195,7 +195,9 @@ mu_file_safety_check (const char *filename, int mode, ...@@ -195,7 +195,9 @@ mu_file_safety_check (const char *filename, int mode,
195 mu_list_t idlist) 195 mu_list_t idlist)
196 { 196 {
197 struct file_check_buffer buf; 197 struct file_check_buffer buf;
198 198
199 if (!filename)
200 return EFAULT;
199 memset (&buf, 0, sizeof (buf)); 201 memset (&buf, 0, sizeof (buf));
200 if (stat (filename, &buf.filst) == 0) 202 if (stat (filename, &buf.filst) == 0)
201 { 203 {
......
...@@ -76,9 +76,10 @@ struct _mu_m_server ...@@ -76,9 +76,10 @@ struct _mu_m_server
76 objects. It is cleared after the objects 76 objects. It is cleared after the objects
77 are opened and attached to the server. */ 77 are opened and attached to the server. */
78 78
79 mu_m_server_conn_fp conn; /* Connection handler function. */ 79 mu_m_server_handler_fp conn; /* Connection handler function. */
80 mu_m_server_prefork_fp prefork;/* Pre-fork function. */ 80 mu_m_server_handler_fp prefork;/* Pre-fork function. */
81 void *data; /* User-supplied data for conn and prefork. */ 81 void *data; /* User-supplied data for conn and prefork. */
82 size_t app_data_size;
82 83
83 int mode; /* Server mode: should be removed. */ 84 int mode; /* Server mode: should be removed. */
84 85
...@@ -98,16 +99,6 @@ struct _mu_m_server ...@@ -98,16 +99,6 @@ struct _mu_m_server
98 description. */ 99 description. */
99 }; 100 };
100 101
101 struct m_srv_config /* Configuration data for a single TCP server. */
102 {
103 mu_m_server_t msrv; /* Parent m-server. */
104 mu_ip_server_t tcpsrv; /* TCP server these data are for. */
105 mu_acl_t acl; /* Access control list for this server. */
106 int single_process; /* Should it run as a single process? */
107 int transcript; /* Enable session transcript. */
108 time_t timeout; /* Idle timeout for this server. */
109 };
110
111 102
112 static int need_cleanup = 0; 103 static int need_cleanup = 0;
113 static int stop = 0; /* FIXME: Must be per-m-server */ 104 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) ...@@ -326,13 +317,13 @@ mu_m_server_set_mode (mu_m_server_t srv, int mode)
326 } 317 }
327 318
328 void 319 void
329 mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_conn_fp conn) 320 mu_m_server_set_conn (mu_m_server_t srv, mu_m_server_handler_fp conn)
330 { 321 {
331 srv->conn = conn; 322 srv->conn = conn;
332 } 323 }
333 324
334 void 325 void
335 mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_prefork_fp fun) 326 mu_m_server_set_prefork (mu_m_server_t srv, mu_m_server_handler_fp fun)
336 { 327 {
337 srv->prefork = fun; 328 srv->prefork = fun;
338 } 329 }
...@@ -433,9 +424,24 @@ mu_m_server_foreground (mu_m_server_t srv) ...@@ -433,9 +424,24 @@ mu_m_server_foreground (mu_m_server_t srv)
433 } 424 }
434 425
435 void 426 void
436 m_srv_config_free (void *data) 427 mu_m_server_set_app_data_size (mu_m_server_t srv, size_t size)
428 {
429 srv->app_data_size = size;
430 }
431
432 int
433 mu_m_server_set_config_size (mu_m_server_t srv, size_t size)
434 {
435 if (size < sizeof (struct mu_srv_config))
436 return EINVAL;
437 srv->app_data_size = size - sizeof (struct mu_srv_config);
438 return 0;
439 }
440
441 void
442 mu_srv_config_free (void *data)
437 { 443 {
438 struct m_srv_config *pconf = data; 444 struct mu_srv_config *pconf = data;
439 /* FIXME */ 445 /* FIXME */
440 free (pconf); 446 free (pconf);
441 } 447 }
...@@ -444,15 +450,15 @@ static int m_srv_conn (int fd, struct sockaddr *sa, int salen, ...@@ -444,15 +450,15 @@ static int m_srv_conn (int fd, struct sockaddr *sa, int salen,
444 void *server_data, void *call_data, 450 void *server_data, void *call_data,
445 mu_ip_server_t srv); 451 mu_ip_server_t srv);
446 452
447 static struct m_srv_config * 453 static struct mu_srv_config *
448 add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type) 454 add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type)
449 { 455 {
450 mu_ip_server_t tcpsrv; 456 mu_ip_server_t tcpsrv;
451 struct m_srv_config *pconf; 457 struct mu_srv_config *pconf;
452 458
453 MU_ASSERT (mu_ip_server_create (&tcpsrv, s, type)); /* FIXME: type */ 459 MU_ASSERT (mu_ip_server_create (&tcpsrv, s, type)); /* FIXME: type */
454 MU_ASSERT (mu_ip_server_set_conn (tcpsrv, m_srv_conn)); 460 MU_ASSERT (mu_ip_server_set_conn (tcpsrv, m_srv_conn));
455 pconf = calloc (1, sizeof (*pconf)); 461 pconf = calloc (1, sizeof (*pconf) + msrv->app_data_size);
456 if (!pconf) 462 if (!pconf)
457 { 463 {
458 mu_error ("%s", mu_strerror (ENOMEM)); 464 mu_error ("%s", mu_strerror (ENOMEM));
...@@ -462,7 +468,7 @@ add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type) ...@@ -462,7 +468,7 @@ add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type)
462 pconf->tcpsrv = tcpsrv; 468 pconf->tcpsrv = tcpsrv;
463 pconf->single_process = 0; 469 pconf->single_process = 0;
464 pconf->timeout = msrv->timeout; 470 pconf->timeout = msrv->timeout;
465 MU_ASSERT (mu_ip_server_set_data (tcpsrv, pconf, m_srv_config_free)); 471 MU_ASSERT (mu_ip_server_set_data (tcpsrv, pconf, mu_srv_config_free));
466 if (!msrv->srvlist) 472 if (!msrv->srvlist)
467 MU_ASSERT (mu_list_create (&msrv->srvlist)); 473 MU_ASSERT (mu_list_create (&msrv->srvlist));
468 MU_ASSERT (mu_list_append (msrv->srvlist, tcpsrv)); 474 MU_ASSERT (mu_list_append (msrv->srvlist, tcpsrv));
...@@ -681,7 +687,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen, ...@@ -681,7 +687,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
681 mu_ip_server_t srv) 687 mu_ip_server_t srv)
682 { 688 {
683 int status; 689 int status;
684 struct m_srv_config *pconf = server_data; 690 struct mu_srv_config *pconf = server_data;
685 691
686 if (mu_m_server_check_acl (pconf->msrv, sa, salen)) 692 if (mu_m_server_check_acl (pconf->msrv, sa, salen))
687 return 0; 693 return 0;
...@@ -701,7 +707,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen, ...@@ -701,7 +707,7 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
701 return 0; 707 return 0;
702 } 708 }
703 if (pconf->msrv->prefork 709 if (pconf->msrv->prefork
704 && pconf->msrv->prefork (fd, pconf->msrv->data, sa, salen)) 710 && pconf->msrv->prefork (fd, sa, salen, pconf, pconf->msrv->data))
705 return 0; 711 return 0;
706 712
707 pid = fork (); 713 pid = fork ();
...@@ -711,8 +717,8 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen, ...@@ -711,8 +717,8 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
711 { 717 {
712 mu_ip_server_shutdown (srv); /* FIXME: does it harm for MU_IP_UDP? */ 718 mu_ip_server_shutdown (srv); /* FIXME: does it harm for MU_IP_UDP? */
713 mu_m_server_restore_signals (pconf->msrv); 719 mu_m_server_restore_signals (pconf->msrv);
714 status = pconf->msrv->conn (fd, sa, salen, pconf->msrv->data, srv, 720 status = pconf->msrv->conn (fd, sa, salen, pconf,
715 pconf->timeout, pconf->transcript); 721 pconf->msrv->data);
716 closelog (); 722 closelog ();
717 exit (status); 723 exit (status);
718 } 724 }
...@@ -722,9 +728,9 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen, ...@@ -722,9 +728,9 @@ m_srv_conn (int fd, struct sockaddr *sa, int salen,
722 } 728 }
723 } 729 }
724 else if (!pconf->msrv->prefork 730 else if (!pconf->msrv->prefork
725 || pconf->msrv->prefork (fd, pconf->msrv->data, sa, salen) == 0) 731 || pconf->msrv->prefork (fd, sa, salen, pconf,
726 pconf->msrv->conn (fd, sa, salen, pconf->msrv->data, srv, 732 pconf->msrv->data) == 0)
727 pconf->timeout, pconf->transcript); 733 pconf->msrv->conn (fd, sa, salen, pconf, pconf->msrv->data);
728 return 0; 734 return 0;
729 } 735 }
730 736
...@@ -802,7 +808,7 @@ server_section_parser (enum mu_cfg_section_stage stage, ...@@ -802,7 +808,7 @@ server_section_parser (enum mu_cfg_section_stage stage,
802 808
803 case mu_cfg_section_end: 809 case mu_cfg_section_end:
804 { 810 {
805 struct m_srv_config *pconf = *section_data; 811 struct mu_srv_config *pconf = *section_data;
806 if (pconf->acl) 812 if (pconf->acl)
807 mu_ip_server_set_acl (pconf->tcpsrv, pconf->acl); 813 mu_ip_server_set_acl (pconf->tcpsrv, pconf->acl);
808 } 814 }
...@@ -904,22 +910,22 @@ static struct mu_cfg_param dot_server_cfg_param[] = { ...@@ -904,22 +910,22 @@ static struct mu_cfg_param dot_server_cfg_param[] = {
904 910
905 static struct mu_cfg_param server_cfg_param[] = { 911 static struct mu_cfg_param server_cfg_param[] = {
906 { "single-process", mu_cfg_bool, 912 { "single-process", mu_cfg_bool,
907 NULL, mu_offsetof (struct m_srv_config, single_process), NULL, 913 NULL, mu_offsetof (struct mu_srv_config, single_process), NULL,
908 N_("Run this server in foreground.") }, 914 N_("Run this server in foreground.") },
909 { "transcript", mu_cfg_bool, 915 { "transcript", mu_cfg_bool,
910 NULL, mu_offsetof (struct m_srv_config, transcript), NULL, 916 NULL, mu_offsetof (struct mu_srv_config, transcript), NULL,
911 N_("Log the session transcript.") }, 917 N_("Log the session transcript.") },
912 { "timeout", mu_cfg_time, 918 { "timeout", mu_cfg_time,
913 NULL, mu_offsetof (struct m_srv_config, timeout), NULL, 919 NULL, mu_offsetof (struct mu_srv_config, timeout), NULL,
914 N_("Set idle timeout.") }, 920 N_("Set idle timeout.") },
915 { "acl", mu_cfg_section, 921 { "acl", mu_cfg_section,
916 NULL, mu_offsetof (struct m_srv_config, acl), NULL, 922 NULL, mu_offsetof (struct mu_srv_config, acl), NULL,
917 N_("Global access control list.") }, 923 N_("Global access control list.") },
918 { NULL } 924 { NULL }
919 }; 925 };
920 926
921 void 927 void
922 mu_m_server_cfg_init () 928 mu_m_server_cfg_init (struct mu_cfg_param *app_param)
923 { 929 {
924 struct mu_cfg_section *section; 930 struct mu_cfg_section *section;
925 if (mu_create_canned_section ("server", &section) == 0) 931 if (mu_create_canned_section ("server", &section) == 0)
...@@ -927,6 +933,8 @@ mu_m_server_cfg_init () ...@@ -927,6 +933,8 @@ mu_m_server_cfg_init ()
927 section->parser = server_section_parser; 933 section->parser = server_section_parser;
928 section->label = N_("ipaddr[:port]"); 934 section->label = N_("ipaddr[:port]");
929 mu_cfg_section_add_params (section, server_cfg_param); 935 mu_cfg_section_add_params (section, server_cfg_param);
936 if (app_param)
937 mu_cfg_section_add_params (section, app_param);
930 } 938 }
931 if (mu_create_canned_section (".server", &section) == 0) 939 if (mu_create_canned_section (".server", &section) == 0)
932 { 940 {
......
...@@ -55,7 +55,7 @@ mu_tls_module_init (enum mu_gocs_op op, void *data) ...@@ -55,7 +55,7 @@ mu_tls_module_init (enum mu_gocs_op op, void *data)
55 55
56 case mu_gocs_op_flush: 56 case mu_gocs_op_flush:
57 #ifdef WITH_TLS 57 #ifdef WITH_TLS
58 mu_init_tls_libs (); 58 mu_init_tls_libs (0);
59 #endif 59 #endif
60 break; 60 break;
61 } 61 }
...@@ -99,14 +99,17 @@ mu_check_tls_environment (void) ...@@ -99,14 +99,17 @@ mu_check_tls_environment (void)
99 return 0; 99 return 0;
100 } 100 }
101 101
102 rc = mu_file_safety_check (mu_tls_module_config.ssl_cafile, 102 if (mu_tls_module_config.ssl_cafile)
103 mu_tls_module_config.ssl_cafile_safety_checks,
104 -1, NULL);
105 if (rc)
106 { 103 {
107 mu_error ("%s: %s", mu_tls_module_config.ssl_cafile, 104 rc = mu_file_safety_check (mu_tls_module_config.ssl_cafile,
108 mu_strerror (rc)); 105 mu_tls_module_config.ssl_cafile_safety_checks,
109 return 0; 106 -1, NULL);
107 if (rc)
108 {
109 mu_error ("%s: %s", mu_tls_module_config.ssl_cafile,
110 mu_strerror (rc));
111 return 0;
112 }
110 } 113 }
111 } 114 }
112 else 115 else
...@@ -126,10 +129,40 @@ _mu_gtls_logger(int level, const char *text) ...@@ -126,10 +129,40 @@ _mu_gtls_logger(int level, const char *text)
126 #endif 129 #endif
127 130
128 int 131 int
129 mu_init_tls_libs (void) 132 mu_init_tls_libs (int x509_setup)
130 { 133 {
131 if (!mu_tls_enable) 134 if (!mu_tls_enable)
132 mu_tls_enable = !gnutls_global_init (); /* Returns 1 on success */ 135 {
136 int rc;
137 if ((rc = gnutls_global_init ()) == GNUTLS_E_SUCCESS)
138 mu_tls_enable = 1;
139 else
140 {
141 mu_error ("gnutls_global_init: %s", gnutls_strerror (rc));
142 return 0;
143 }
144 }
145
146 if (x509_setup && !x509_cred)
147 {
148 mu_diag_output (MU_DIAG_INFO, _("initializing X509..."));
149 gnutls_certificate_allocate_credentials (&x509_cred);
150 if (mu_tls_module_config.ssl_cafile)
151 gnutls_certificate_set_x509_trust_file (x509_cred,
152 mu_tls_module_config.ssl_cafile,
153 GNUTLS_X509_FMT_PEM);
154
155 gnutls_certificate_set_x509_key_file (x509_cred,
156 mu_tls_module_config.ssl_cert,
157 mu_tls_module_config.ssl_key,
158 GNUTLS_X509_FMT_PEM);
159
160 gnutls_dh_params_init (&dh_params);
161 gnutls_dh_params_generate2 (dh_params, DH_BITS);
162 gnutls_certificate_set_dh_params (x509_cred, dh_params);
163 mu_diag_output (MU_DIAG_INFO, _("finished initializing X509"));
164 }
165
133 #ifdef DEBUG_TLS 166 #ifdef DEBUG_TLS
134 gnutls_global_set_log_function (_mu_gtls_logger); 167 gnutls_global_set_log_function (_mu_gtls_logger);
135 gnutls_global_set_log_level (110); 168 gnutls_global_set_log_level (110);
...@@ -141,17 +174,14 @@ void ...@@ -141,17 +174,14 @@ void
141 mu_deinit_tls_libs (void) 174 mu_deinit_tls_libs (void)
142 { 175 {
143 if (mu_tls_enable) 176 if (mu_tls_enable)
144 gnutls_global_deinit (); 177 {
178 if (x509_cred)
179 gnutls_certificate_free_credentials (x509_cred);
180 gnutls_global_deinit ();
181 }
145 mu_tls_enable = 0; 182 mu_tls_enable = 0;
146 } 183 }
147 184
148 static void
149 generate_dh_params (void)
150 {
151 gnutls_dh_params_init (&dh_params);
152 gnutls_dh_params_generate2 (dh_params, DH_BITS);
153 }
154
155 static gnutls_session 185 static gnutls_session
156 initialize_tls_session (void) 186 initialize_tls_session (void)
157 { 187 {
...@@ -382,28 +412,8 @@ _tls_server_open (mu_stream_t stream) ...@@ -382,28 +412,8 @@ _tls_server_open (mu_stream_t stream)
382 if (!stream || sp->state != state_init) 412 if (!stream || sp->state != state_init)
383 return EINVAL; 413 return EINVAL;
384 414
385 mu_init_tls_libs (); 415 mu_init_tls_libs (1);
386 416
387 gnutls_certificate_allocate_credentials (&x509_cred);
388
389 if (mu_tls_module_config.ssl_cafile)
390 gnutls_certificate_set_x509_trust_file (x509_cred,
391 mu_tls_module_config.ssl_cafile,
392 GNUTLS_X509_FMT_PEM);
393
394 rc = gnutls_certificate_set_x509_key_file (x509_cred,
395 mu_tls_module_config.ssl_cert,
396 mu_tls_module_config.ssl_key,
397 GNUTLS_X509_FMT_PEM);
398 if (rc < 0)
399 {
400 sp->tls_err = rc;
401 return EIO;
402 }
403
404 generate_dh_params ();
405 gnutls_certificate_set_dh_params (x509_cred, dh_params);
406
407 sp->session = initialize_tls_session (); 417 sp->session = initialize_tls_session ();
408 mu_stream_ioctl (stream, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, transport); 418 mu_stream_ioctl (stream, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, transport);
409 gnutls_transport_set_ptr2 (sp->session, 419 gnutls_transport_set_ptr2 (sp->session,
...@@ -478,13 +488,12 @@ _tls_client_open (mu_stream_t stream) ...@@ -478,13 +488,12 @@ _tls_client_open (mu_stream_t stream)
478 switch (sp->state) 488 switch (sp->state)
479 { 489 {
480 case state_closed: 490 case state_closed:
481 gnutls_certificate_free_credentials (x509_cred);
482 if (sp->session) 491 if (sp->session)
483 gnutls_deinit (sp->session); 492 gnutls_deinit (sp->session);
484 /* FALLTHROUGH */ 493 /* FALLTHROUGH */
485 494
486 case state_init: 495 case state_init:
487 mu_init_tls_libs (); 496 mu_init_tls_libs (0);
488 prepare_client_session (stream); 497 prepare_client_session (stream);
489 rc = gnutls_handshake (sp->session); 498 rc = gnutls_handshake (sp->session);
490 if (rc < 0) 499 if (rc < 0)
...@@ -630,8 +639,6 @@ _tls_done (struct _mu_stream *stream) ...@@ -630,8 +639,6 @@ _tls_done (struct _mu_stream *stream)
630 { 639 {
631 struct _mu_tls_stream *sp = (struct _mu_tls_stream *) stream; 640 struct _mu_tls_stream *sp = (struct _mu_tls_stream *) stream;
632 641
633 if (x509_cred)
634 gnutls_certificate_free_credentials (x509_cred);
635 if (sp->session && sp->state == state_closed) 642 if (sp->session && sp->state == state_closed)
636 { 643 {
637 gnutls_deinit (sp->session); 644 gnutls_deinit (sp->session);
......
...@@ -52,11 +52,11 @@ cb2_safety_checks (const char *name, void *data) ...@@ -52,11 +52,11 @@ cb2_safety_checks (const char *name, void *data)
52 { 52 {
53 int defval; 53 int defval;
54 54
55 if (data == &tls_settings.ssl_key) 55 if (data == &tls_settings.ssl_key_safety_checks)
56 defval = SSL_KEY_FILE_CHECKS; 56 defval = SSL_KEY_FILE_CHECKS;
57 else if (data == &tls_settings.ssl_cert) 57 else if (data == &tls_settings.ssl_cert_safety_checks)
58 defval = SSL_CERT_FILE_CHECKS; 58 defval = SSL_CERT_FILE_CHECKS;
59 else if (data == &tls_settings.ssl_cafile) 59 else if (data == &tls_settings.ssl_cafile_safety_checks)
60 defval = SSL_CA_FILE_CHECKS; 60 defval = SSL_CA_FILE_CHECKS;
61 else 61 else
62 { 62 {
......
...@@ -574,8 +574,9 @@ typedef union ...@@ -574,8 +574,9 @@ typedef union
574 } all_addr_t; 574 } all_addr_t;
575 575
576 int 576 int
577 lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data, 577 lmtp_connection (int fd, struct sockaddr *sa, int salen,
578 mu_ip_server_t srv, time_t timeout, int transcript) 578 struct mu_srv_config *pconf,
579 void *data)
579 { 580 {
580 mu_stream_t str; 581 mu_stream_t str;
581 int rc; 582 int rc;
...@@ -588,9 +589,9 @@ lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data, ...@@ -588,9 +589,9 @@ lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data,
588 } 589 }
589 mu_stream_set_buffer (str, mu_buffer_line, 0); 590 mu_stream_set_buffer (str, mu_buffer_line, 0);
590 591
591 if (transcript || maidag_transcript) 592 if (pconf->transcript || maidag_transcript)
592 str = lmtp_transcript (str); 593 str = lmtp_transcript (str);
593 lmtp_loop (str, timeout); 594 lmtp_loop (str, pconf->timeout);
594 mu_stream_destroy (&str); 595 mu_stream_destroy (&str);
595 return 0; 596 return 0;
596 } 597 }
......
...@@ -525,7 +525,7 @@ main (int argc, char *argv[]) ...@@ -525,7 +525,7 @@ main (int argc, char *argv[])
525 525
526 mu_tcpwrapper_cfg_init (); 526 mu_tcpwrapper_cfg_init ();
527 mu_acl_cfg_init (); 527 mu_acl_cfg_init ();
528 mu_m_server_cfg_init (); 528 mu_m_server_cfg_init (NULL);
529 maidag_cfg_init (); 529 maidag_cfg_init ();
530 530
531 /* Parse command line */ 531 /* Parse command line */
......
...@@ -150,8 +150,9 @@ int deliver_to_user (mu_message_t msg, char *dest_id, char **errp); ...@@ -150,8 +150,9 @@ int deliver_to_user (mu_message_t msg, char *dest_id, char **errp);
150 150
151 int maidag_stdio_delivery (maidag_delivery_fn fun, int argc, char **argv); 151 int maidag_stdio_delivery (maidag_delivery_fn fun, int argc, char **argv);
152 int maidag_lmtp_server (void); 152 int maidag_lmtp_server (void);
153 int lmtp_connection (int fd, struct sockaddr *sa, int salen, void *data, 153 int lmtp_connection (int fd, struct sockaddr *sa, int salen,
154 mu_ip_server_t srv, time_t timeout, int transcript); 154 struct mu_srv_config *pconf,
155 void *data);
155 156
156 void maidag_error (const char *fmt, ...) MU_PRINTFLIKE(1, 2); 157 void maidag_error (const char *fmt, ...) MU_PRINTFLIKE(1, 2);
157 void notify_biff (mu_mailbox_t mbox, char *name, size_t size); 158 void notify_biff (mu_mailbox_t mbox, char *name, size_t size);
......
...@@ -93,6 +93,10 @@ pop3d_abquit (int reason) ...@@ -93,6 +93,10 @@ pop3d_abquit (int reason)
93 mu_diag_output (MU_DIAG_INFO, _("no socket to send to")); 93 mu_diag_output (MU_DIAG_INFO, _("no socket to send to"));
94 break; 94 break;
95 95
96 case ERR_FILE:
97 code = EX_IOERR;
98 break;
99
96 case ERR_PROTO: 100 case ERR_PROTO:
97 code = EX_PROTOCOL; 101 code = EX_PROTOCOL;
98 mu_diag_output (MU_DIAG_INFO, _("remote protocol error")); 102 mu_diag_output (MU_DIAG_INFO, _("remote protocol error"));
...@@ -125,7 +129,7 @@ pop3d_abquit (int reason) ...@@ -125,7 +129,7 @@ pop3d_abquit (int reason)
125 } 129 }
126 130
127 void 131 void
128 pop3d_setio (int ifd, int ofd) 132 pop3d_setio (int ifd, int ofd, int tls)
129 { 133 {
130 mu_stream_t str, istream, ostream; 134 mu_stream_t str, istream, ostream;
131 135
...@@ -137,11 +141,26 @@ pop3d_setio (int ifd, int ofd) ...@@ -137,11 +141,26 @@ pop3d_setio (int ifd, int ofd)
137 if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ)) 141 if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ))
138 pop3d_abquit (ERR_NO_IFILE); 142 pop3d_abquit (ERR_NO_IFILE);
139 mu_stream_set_buffer (istream, mu_buffer_line, 0); 143 mu_stream_set_buffer (istream, mu_buffer_line, 0);
140 144
141 if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE)) 145 if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE))
142 pop3d_abquit (ERR_NO_OFILE); 146 pop3d_abquit (ERR_NO_OFILE);
143 147
144 /* Combine the two streams into an I/O one. */ 148 /* Combine the two streams into an I/O one. */
149 #ifdef WITH_TLS
150 if (tls)
151 {
152 int rc = mu_tls_server_stream_create (&str, istream, ostream, 0);
153 if (rc)
154 {
155 mu_stream_unref (istream);
156 mu_stream_unref (ostream);
157 mu_error (_("failed to create TLS stream: %s"), mu_strerror (rc));
158 pop3d_abquit (ERR_FILE);
159 }
160 tls_done = 1;
161 }
162 else
163 #endif
145 if (mu_iostream_create (&str, istream, ostream)) 164 if (mu_iostream_create (&str, istream, ostream))
146 pop3d_abquit (ERR_FILE); 165 pop3d_abquit (ERR_FILE);
147 166
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
18 #include "pop3d.h" 18 #include "pop3d.h"
19 #include "mailutils/pam.h" 19 #include "mailutils/pam.h"
20 #include "mailutils/libargp.h" 20 #include "mailutils/libargp.h"
21 #include "mailutils/pop3.h"
21 #include "tcpwrap.h" 22 #include "tcpwrap.h"
22 23
23 mu_mailbox_t mbox; 24 mu_mailbox_t mbox;
...@@ -107,6 +108,19 @@ cb_bulletin_db (void *data, mu_config_value_t *val) ...@@ -107,6 +108,19 @@ cb_bulletin_db (void *data, mu_config_value_t *val)
107 } 108 }
108 #endif 109 #endif
109 110
111 struct pop3d_srv_config
112 {
113 struct mu_srv_config m_cfg;
114 int tls;
115 };
116
117 static struct mu_cfg_param pop3d_srv_param[] = {
118 { "tls", mu_cfg_bool, NULL, mu_offsetof (struct pop3d_srv_config, tls), NULL,
119 N_("Use TLS encryption for this server")
120 },
121 { NULL }
122 };
123
110 static struct mu_cfg_param pop3d_cfg_param[] = { 124 static struct mu_cfg_param pop3d_cfg_param[] = {
111 { "undelete", mu_cfg_bool, &undelete_on_startup, 0, NULL, 125 { "undelete", mu_cfg_bool, &undelete_on_startup, 0, NULL,
112 N_("On startup, clear deletion marks from all the messages.") }, 126 N_("On startup, clear deletion marks from all the messages.") },
...@@ -247,9 +261,10 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs) ...@@ -247,9 +261,10 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs)
247 executes the proper functions. Also handles the bulk of error reporting. 261 executes the proper functions. Also handles the bulk of error reporting.
248 Arguments: 262 Arguments:
249 ifd -- input descriptor 263 ifd -- input descriptor
250 ofd -- output descriptor */ 264 ofd -- output descriptor
265 tls -- initiate encrypted connection */
251 int 266 int
252 pop3d_mainloop (int ifd, int ofd) 267 pop3d_mainloop (int ifd, int ofd, int tls)
253 { 268 {
254 int status = OK; 269 int status = OK;
255 char buffer[512]; 270 char buffer[512];
...@@ -258,7 +273,7 @@ pop3d_mainloop (int ifd, int ofd) ...@@ -258,7 +273,7 @@ pop3d_mainloop (int ifd, int ofd)
258 273
259 mu_set_signals (pop3d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab)); 274 mu_set_signals (pop3d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab));
260 275
261 pop3d_setio (ifd, ofd); 276 pop3d_setio (ifd, ofd, tls);
262 277
263 state = initial_state; 278 state = initial_state;
264 279
...@@ -324,13 +339,16 @@ pop3d_mainloop (int ifd, int ofd) ...@@ -324,13 +339,16 @@ pop3d_mainloop (int ifd, int ofd)
324 } 339 }
325 340
326 int 341 int
327 pop3d_connection (int fd, struct sockaddr *sa, int salen, void *data, 342 pop3d_connection (int fd, struct sockaddr *sa, int salen,
328 mu_ip_server_t srv, time_t timeout, int transcript) 343 struct mu_srv_config *pconf,
344 void *data)
329 { 345 {
330 idle_timeout = timeout; 346 struct pop3d_srv_config *cfg = (struct pop3d_srv_config *) pconf;
331 if (pop3d_transcript != transcript) 347
332 pop3d_transcript = transcript; 348 idle_timeout = pconf->timeout;
333 pop3d_mainloop (fd, fd); 349 pop3d_transcript = pconf->transcript;
350
351 pop3d_mainloop (fd, fd, cfg->tls);
334 return 0; 352 return 0;
335 } 353 }
336 354
...@@ -370,11 +388,12 @@ main (int argc, char **argv) ...@@ -370,11 +388,12 @@ main (int argc, char **argv)
370 mu_tcpwrapper_cfg_init (); 388 mu_tcpwrapper_cfg_init ();
371 manlock_cfg_init (); 389 manlock_cfg_init ();
372 mu_acl_cfg_init (); 390 mu_acl_cfg_init ();
373 mu_m_server_cfg_init (); 391 mu_m_server_cfg_init (pop3d_srv_param);
374 392
375 mu_argp_init (NULL, NULL); 393 mu_argp_init (NULL, NULL);
376 394
377 mu_m_server_create (&server, program_version); 395 mu_m_server_create (&server, program_version);
396 mu_m_server_set_config_size (server, sizeof (struct pop3d_srv_config));
378 mu_m_server_set_conn (server, pop3d_connection); 397 mu_m_server_set_conn (server, pop3d_connection);
379 mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork); 398 mu_m_server_set_prefork (server, mu_tcp_wrapper_prefork);
380 mu_m_server_set_mode (server, MODE_INTERACTIVE); 399 mu_m_server_set_mode (server, MODE_INTERACTIVE);
...@@ -451,7 +470,7 @@ main (int argc, char **argv) ...@@ -451,7 +470,7 @@ main (int argc, char **argv)
451 tls_available = mu_check_tls_environment (); 470 tls_available = mu_check_tls_environment ();
452 if (tls_available) 471 if (tls_available)
453 { 472 {
454 tls_available = mu_init_tls_libs (); 473 tls_available = mu_init_tls_libs (1);
455 if (tls_available) 474 if (tls_available)
456 enable_stls (); 475 enable_stls ();
457 } 476 }
...@@ -469,7 +488,7 @@ main (int argc, char **argv) ...@@ -469,7 +488,7 @@ main (int argc, char **argv)
469 { 488 {
470 /* Make sure we are in the root directory. */ 489 /* Make sure we are in the root directory. */
471 chdir ("/"); 490 chdir ("/");
472 status = pop3d_mainloop (MU_STDIN_FD, MU_STDOUT_FD); 491 status = pop3d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, 0);
473 } 492 }
474 493
475 if (status) 494 if (status)
......
...@@ -236,7 +236,7 @@ extern void enable_stls (void); ...@@ -236,7 +236,7 @@ extern void enable_stls (void);
236 #endif /* WITH_TLS */ 236 #endif /* WITH_TLS */
237 extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2); 237 extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2);
238 238
239 extern void pop3d_setio (int, int); 239 extern void pop3d_setio (int, int, int);
240 extern char *pop3d_readline (char *, size_t); 240 extern char *pop3d_readline (char *, size_t);
241 extern void pop3d_flush_output (void); 241 extern void pop3d_flush_output (void);
242 242
......