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.
Showing
19 changed files
with
261 additions
and
148 deletions
... | @@ -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", §ion) == 0) | 931 | if (mu_create_canned_section ("server", §ion) == 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", §ion) == 0) | 939 | if (mu_create_canned_section (".server", §ion) == 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 | ... | ... |
-
Please register or sign in to post a comment