Commit 24124842 2412484207346815cb2a1a7ef3c3aa8e6e093fba by Sergey Poznyakoff

* configure.ac: Add TCP wrappers support.

* imap4d/Makefile.am, mu_daemon_argp_parser (LDADD): Add
TCPWRAP_LIBRARIES.
* imap4d/imap4d.c: Include tcpwrap.h
(imap4d_mainloop): Check the connection using tcp wrappers.
* imap4d/preauth.c: Fix a typo in the comment.
* maidag/maidag.h: Include tcpwrap.h
* maidag/maidag.c, maidag/lmtp.c: Add TCP wrappers support.
* pop3d/pop3d.c: Include tcpwrap.h
(pop3d_mainloop): Check the connection using tcp wrappers.
* lib/Makefile.am: Add tcpwrap.c and tcpwrap.h
* lib/tcpwrap.c: New file.
* lib/tcpwrap.h: New file.
* libargp/common.c (mu_daemon_argp_parser): Bugfix.
1 parent e0f4a7db
1 2007-12-05 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * configure.ac: Add TCP wrappers support.
4 * imap4d/Makefile.am, mu_daemon_argp_parser (LDADD): Add
5 TCPWRAP_LIBRARIES.
6 * imap4d/imap4d.c: Include tcpwrap.h
7 (imap4d_mainloop): Check the connection using tcp wrappers.
8 * imap4d/preauth.c: Fix a typo in the comment.
9 * maidag/maidag.h: Include tcpwrap.h
10 * maidag/maidag.c, maidag/lmtp.c: Add TCP wrappers support.
11 * pop3d/pop3d.c: Include tcpwrap.h
12 (pop3d_mainloop): Check the connection using tcp wrappers.
13 * lib/Makefile.am: Add tcpwrap.c and tcpwrap.h
14 * lib/tcpwrap.c: New file.
15 * lib/tcpwrap.h: New file.
16 * libargp/common.c (mu_daemon_argp_parser): Bugfix.
17
1 2007-12-04 Sergey Poznyakoff <gray@gnu.org.ua> 18 2007-12-04 Sergey Poznyakoff <gray@gnu.org.ua>
2 19
3 II. Extend --config-help output. Each configuration parameter 20 II. Extend --config-help output. Each configuration parameter
......
1 GNU mailutils NEWS -- history of user-visible changes. 2007-12-03 1 GNU mailutils NEWS -- history of user-visible changes. 2007-12-05
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3 See the end of file for copying conditions. 3 See the end of file for copying conditions.
4 4
...@@ -9,7 +9,86 @@ Version 1.2.90: ...@@ -9,7 +9,86 @@ Version 1.2.90:
9 9
10 * New configuration file format. 10 * New configuration file format.
11 11
12 * Diagnostic and debugging functions essentially rewritten. 12 * Programs
13
14 ** Debugging and online help
15
16 Each Mailutils utility understands two additional command line
17 options:
18
19 --debug-level=LEVEL Set Mailutils debugging level.
20 --debug-line-info Show source info with debugging messages.
21
22 (see also `** Global debugging and verbosity settings.', below)
23
24 The programs using configuration file facility also understand the
25 --config-help command line option. This option prints on the standard
26 output the detailed description of configuration file statements that
27 affect the given program.
28
29 ** New utility `maidag'
30
31 Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to
32 run in both traditional and LMTP mode and to deliver mails to various
33 mailbox formats. It is also able to process incoming messages using
34 Sieve or Scheme scripts and, based on results of this processing,
35 to take a decision on whether to actually deliver and where to
36 deliver them.
37
38 ** New Sieve action `pipe'
39
40 Syntax: pipe [:envelope] <command line: string>
41
42 This action executes the given <command line> and pipes the message to
43 its standard input. If the :envelope tag is given, the envelope of the
44 message is piped as well.
45
46 ** Client SMTP STARTTLS support
47
48 ** Support for new protocols: POPS (pops://) and IMAPS (imaps://),
49
50 ** LDAP support (authentication and authorization).
51
52 ** Support for TCP wrappers.
53
54 The support for TCP wrappers is added to the daemon programs (imap4d,
55 pop3d, maidag). The support is controlled at compile time by the
56 --with-tcpwrappers command line options to configure. By default, it
57 is enabled if libwrap presence is detected. A set of configuration
58 file statements are provided for fine tuning TCP wrappers at run-time.
59
60 ** pop3d: Fixed APOP handling.
61
62 ** imap4d supports PREAUTH mode.
63
64 Three mechanisms are provided for authentifying the connection in
65 PREAUTH mode:
66
67 1. stdio - PREAUTH mode is enabled automatically if imap4d is started
68 from command line in interactive mode (-i command line
69 option). The current login name is used as the user name.
70
71 2. ident - The remote machine is asked about the requester identity
72 using the identification protocol (RFC 1413). Both plaintext and
73 DES encrypted replies are understood.
74
75 3. prog - Imap4d invokes an external program to authenticate the
76 connection. Four arguments are supplied to the program:
77
78 1) Remote IP address in dotted-quad notation;
79 2) Remote port number;
80 3) Local IP address (currently "0.0.0.0");
81 4) Local port number.
82
83 If the connection is authenticated, the program should print the
84 user name, followed by a newline character, on its standard
85 output and exit with code 0.
86
87 Otherwise, it shoud exit with a non-zero exit code.
88
89 * Libraries
90
91 ** Diagnostic and debugging functions essentially rewritten.
13 92
14 A set of debugging macros, MU_DEBUG0 through MU_DEBUG11, is provided. 93 A set of debugging macros, MU_DEBUG0 through MU_DEBUG11, is provided.
15 New functions mu_debug_printf and mu_debug_vprintf allow for flexible 94 New functions mu_debug_printf and mu_debug_vprintf allow for flexible
...@@ -43,7 +122,7 @@ approach is recommended to use instead of mu_error_set_print: ...@@ -43,7 +122,7 @@ approach is recommended to use instead of mu_error_set_print:
43 mu_diag_get_debug (&debug); 122 mu_diag_get_debug (&debug);
44 mu_debug_set_print (debug, new_printer, NULL); 123 mu_debug_set_print (debug, new_printer, NULL);
45 124
46 * Global debugging and verbosity settings. 125 ** Global debugging and verbosity settings.
47 126
48 These settings provide default values for mu_debug_t objects created 127 These settings provide default values for mu_debug_t objects created
49 by various library objects. The following functions are provided for 128 by various library objects. The following functions are provided for
...@@ -53,27 +132,12 @@ dealing with global debugging level: ...@@ -53,27 +132,12 @@ dealing with global debugging level:
53 int mu_global_debug_set_level (const char *object_name, unsigned level); 132 int mu_global_debug_set_level (const char *object_name, unsigned level);
54 int mu_global_debug_clear_level (const char *object_name); 133 int mu_global_debug_clear_level (const char *object_name);
55 134
56 Each Mailutils utility understands two additional command line 135 ** New function mu_mailbox_sync
57 options:
58
59 --debug-level=LEVEL Set Mailutils debugging level.
60 --debug-line-info Show source info with debugging messages.
61
62 * New utility `maidag'
63
64 Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to
65 run in both traditional and LMTP mode and to deliver mails to various
66 mailbox formats. It is also able to process incoming messages using
67 Sieve or Scheme scripts and, based on results of this processing,
68 to take a decision on whether to actually deliver and where to
69 deliver them.
70
71 * New function mu_mailbox_sync
72 136
73 It supercedes mu_mailbox_save_attributes, which is now considered 137 It supercedes mu_mailbox_save_attributes, which is now considered
74 deprecated. 138 deprecated.
75 139
76 * Observable event handling 140 ** Observable event handling
77 141
78 Each event type is associated with an event-specific data 142 Each event type is associated with an event-specific data
79 pointer. This pointer is passed to event handling functions along with 143 pointer. This pointer is passed to event handling functions along with
...@@ -92,14 +156,6 @@ message is appended to the mailbox. ...@@ -92,14 +156,6 @@ message is appended to the mailbox.
92 A set of functions are provided for so-called `quick access' to mail 156 A set of functions are provided for so-called `quick access' to mail
93 messages. FIXME: describe it. 157 messages. FIXME: describe it.
94 158
95 * New Sieve action `pipe'
96
97 Syntax: pipe [:envelope] <command line: string>
98
99 This action executes the given <command line> and pipes the message to
100 its standard input. If the :envelope tag is given, the envelope of the
101 message is piped as well.
102
103 * New `aget' and `sget' accessors for mu_url_t 159 * New `aget' and `sget' accessors for mu_url_t
104 160
105 The following new accessors are provided: 161 The following new accessors are provided:
...@@ -138,41 +194,6 @@ It is parsed as an absolute file name `/a/b'. ...@@ -138,41 +194,6 @@ It is parsed as an absolute file name `/a/b'.
138 Previous versions incorrectly understood such an URL as `a/b' 194 Previous versions incorrectly understood such an URL as `a/b'
139 (relative file name). 195 (relative file name).
140 196
141 * Client SMTP STARTTLS support
142
143 * Support for new protocols: POPS (pops://) and IMAPS (imaps://),
144
145 * LDAP support (authentication and authorization).
146
147 * Fixed APOP handling.
148
149 * imap4d supports PREAUTH mode.
150
151 Three mechanisms are provided for authentifying the connection in
152 PREAUTH mode:
153
154 1. stdio - PREAUTH mode is enabled automatically if imap4d is started
155 from command line in interactive mode (-i command line
156 option). The current login name is used as the user name.
157
158 2. ident - The remote machine is asked about the requester identity
159 using the identification protocol (RFC 1413). Both plaintext and
160 DES encrypted replies are understood.
161
162 3. prog - Imap4d invokes an external program to authenticate the
163 connection. Four arguments are supplied to the program:
164
165 1) Remote IP address in dotted-quad notation;
166 2) Remote port number;
167 3) Local IP address (currently "0.0.0.0");
168 4) Local port number.
169
170 If the connection is authenticated, the program should print the
171 user name, followed by a newline character, on its standard
172 output and exit with code 0.
173
174 Otherwise, it shoud exit with a non-zero exit code.
175
176 * Remove v0.6 compatibility layer. 197 * Remove v0.6 compatibility layer.
177 198
178 199
......
...@@ -75,6 +75,7 @@ status_gsasl=no ...@@ -75,6 +75,7 @@ status_gsasl=no
75 status_mysql=no 75 status_mysql=no
76 status_pgsql=no 76 status_pgsql=no
77 status_ldap=no 77 status_ldap=no
78 status_tcpwrap=maybe
78 79
79 dnl Internationalization macros. 80 dnl Internationalization macros.
80 AM_GNU_GETTEXT([external], [need-ngettext]) 81 AM_GNU_GETTEXT([external], [need-ngettext])
...@@ -148,6 +149,43 @@ case "${enableval}" in ...@@ -148,6 +149,43 @@ case "${enableval}" in
148 *) AC_MSG_ERROR([bad value ${enableval} for --disable-pam]) ;; 149 *) AC_MSG_ERROR([bad value ${enableval} for --disable-pam]) ;;
149 esac],[testpam=yes]) 150 esac],[testpam=yes])
150 151
152 AC_ARG_WITH(tcp-wrappers,
153 AC_HELP_STRING([--with-tcp-wrappers],
154 [compile with TCP wrappers (libwrap) support]),
155 [status_tcpwrap=${withval}],
156 [status_tcpwrap=maybe])
157
158 saved_LIBS=$LIBS
159 TCPWRAP_LIBRARIES=
160 case $status_tcpwrap in
161 yes) AC_CHECK_LIB(wrap, main,,
162 [AC_MSG_ERROR([Required library libwrap not found])])
163 AC_CHECK_LIB(nsl, main,
164 [TCPWRAP_LIBRARIES=-lnsl])
165 AC_CHECK_HEADERS(tcpd.h,,
166 [AC_MSG_ERROR([Required header tcpd.h not found])])
167 status_tcpwrap=yes
168 ;;
169
170 maybe)
171 AC_CHECK_LIB(wrap, main,
172 [status_tcpwrap=yes],
173 [status_tcpwrap=no])
174 AC_CHECK_LIB(nsl, main, [TCPWRAP_LIBRARIES=-lnsl])
175 AC_CHECK_HEADERS(tcpd.h,
176 [status_tcpwrap=yes],
177 [status_tcpwrap=no])
178 ;;
179 no) ;;
180 esac
181 LIBS=$saved_LIBS
182
183 if test "$status_tcpwrap" = "yes"; then
184 AC_SUBST(TCPWRAP_LIBRARIES, "$TCPWRAP_LIBRARIES -lwrap")
185 AC_DEFINE_UNQUOTED(WITH_LIBWRAP, 1,
186 [Define to 1 to use tcp wrappers.])
187 fi
188
151 AC_ARG_ENABLE([pthread], 189 AC_ARG_ENABLE([pthread],
152 AC_HELP_STRING([--disable-pthread], 190 AC_HELP_STRING([--disable-pthread],
153 [disable pthread]), 191 [disable pthread]),
...@@ -1070,6 +1108,7 @@ Use GNU TLS.................... $status_gnutls ...@@ -1070,6 +1108,7 @@ Use GNU TLS.................... $status_gnutls
1070 Use GSASL...................... $status_gsasl 1108 Use GSASL...................... $status_gsasl
1071 Use GSSAPI..................... $status_gssapi 1109 Use GSSAPI..................... $status_gssapi
1072 Use Guile...................... $status_guile 1110 Use Guile...................... $status_guile
1111 Use TCP wrappers............... $status_tcpwrap
1073 Pthread support................ $status_pthread 1112 Pthread support................ $status_pthread
1074 Readline support............... $status_readline 1113 Readline support............... $status_readline
1075 MySQL support.................. $status_mysql 1114 MySQL support.................. $status_mysql
...@@ -1104,6 +1143,7 @@ status_gnutls=$WITH_GNUTLS ...@@ -1104,6 +1143,7 @@ status_gnutls=$WITH_GNUTLS
1104 status_gsasl=$status_gsasl 1143 status_gsasl=$status_gsasl
1105 status_gssapi=$WITH_GSSAPI 1144 status_gssapi=$WITH_GSSAPI
1106 status_guile=$useguile 1145 status_guile=$useguile
1146 status_tcpwrap=$status_tcpwrap
1107 status_pthread=$usepthread 1147 status_pthread=$usepthread
1108 status_readline=$usereadline 1148 status_readline=$usereadline
1109 status_mysql=$status_mysql 1149 status_mysql=$status_mysql
......
...@@ -70,7 +70,7 @@ imap4d_LDADD = \ ...@@ -70,7 +70,7 @@ imap4d_LDADD = \
70 ${MU_LIB_AUTH}\ 70 ${MU_LIB_AUTH}\
71 @MU_AUTHLIBS@ \ 71 @MU_AUTHLIBS@ \
72 ${MU_LIB_MAILUTILS}\ 72 ${MU_LIB_MAILUTILS}\
73 @SERV_AUTHLIBS@ @MU_COMMON_LIBRARIES@ 73 @SERV_AUTHLIBS@ @MU_COMMON_LIBRARIES@ @TCPWRAP_LIBRARIES@
74 74
75 ## This kludge is necessary to correctly establish imap4d -> IMAP_AUTHOBJS 75 ## This kludge is necessary to correctly establish imap4d -> IMAP_AUTHOBJS
76 ## and imap4d -> MU_AUTHLIBS dependencies. Automake stupidly refuses to 76 ## and imap4d -> MU_AUTHLIBS dependencies. Automake stupidly refuses to
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
22 # include <mailutils/gsasl.h> 22 # include <mailutils/gsasl.h>
23 #endif 23 #endif
24 #include "mailutils/libargp.h" 24 #include "mailutils/libargp.h"
25 #include "tcpwrap.h"
25 26
26 mu_mailbox_t mbox; 27 mu_mailbox_t mbox;
27 char *homedir; 28 char *homedir;
28 int state = STATE_NONAUTH; 29 int state = STATE_NONAUTH;
29 int debug_mode = 0;
30 struct mu_auth_data *auth_data; 30 struct mu_auth_data *auth_data;
31 31
32 struct mu_gocs_daemon default_gocs_daemon = { 32 struct mu_gocs_daemon default_gocs_daemon = {
...@@ -299,7 +299,8 @@ static struct mu_cfg_param imap4d_cfg_param[] = { ...@@ -299,7 +299,8 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
299 { "ident-keyfile", mu_cfg_string, &ident_keyfile, NULL, 299 { "ident-keyfile", mu_cfg_string, &ident_keyfile, NULL,
300 N_("Name of DES keyfile for decoding ecrypted ident responses.") }, 300 N_("Name of DES keyfile for decoding ecrypted ident responses.") },
301 { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, NULL, 301 { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, NULL,
302 N_("Use only ecrypted ident responses.") }, 302 N_("Use only encrypted ident responses.") },
303 TCP_WRAPPERS_CONFIG
303 { NULL } 304 { NULL }
304 }; 305 };
305 306
...@@ -343,12 +344,7 @@ main (int argc, char **argv) ...@@ -343,12 +344,7 @@ main (int argc, char **argv)
343 mu_pam_service = "gnu-imap4d"; 344 mu_pam_service = "gnu-imap4d";
344 #endif 345 #endif
345 346
346 if (mu_gocs_daemon.mode == MODE_INTERACTIVE) 347 if (mu_gocs_daemon.mode == MODE_DAEMON)
347 {
348 if (preauth_mode != preauth_stdio)
349 debug_mode = 1;
350 }
351 else
352 { 348 {
353 /* Normal operation: */ 349 /* Normal operation: */
354 /* First we want our group to be mail so we can access the spool. */ 350 /* First we want our group to be mail so we can access the spool. */
...@@ -457,25 +453,66 @@ imap4d_session_setup (char *username) ...@@ -457,25 +453,66 @@ imap4d_session_setup (char *username)
457 return imap4d_session_setup0 (); 453 return imap4d_session_setup0 ();
458 } 454 }
459 455
456 int
457 get_client_address (int fd, struct sockaddr_in *pcs)
458 {
459 int len = sizeof *pcs;
460
461 if (getpeername (fd, (struct sockaddr *) pcs, &len) < 0)
462 {
463 mu_diag_output (MU_DIAG_ERROR,
464 _("Cannot obtain IP address of client: %s"),
465 strerror (errno));
466 return 1;
467 }
468
469 mu_diag_output (MU_DIAG_INFO, _("Connect from %s"),
470 inet_ntoa (pcs->sin_addr));
471 return 0;
472 }
473
460 static int 474 static int
461 imap4d_mainloop (int fd, FILE *infile, FILE *outfile) 475 imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
462 { 476 {
463 char *text; 477 char *text;
478 struct sockaddr_in cs;
479 int debug_mode = isatty (fd);
464 480
465 /* Reset hup to exit. */ 481 mu_diag_output (MU_DIAG_INFO, _("Incoming connection opened"));
482 if (!debug_mode)
483 {
484 if (get_client_address (fd, &cs) == 0)
485 {
486 if (!mu_tcpwrapper_access (fd))
487 {
488 mu_error (_("Access from %s blocked."), inet_ntoa (cs.sin_addr));
489 return 1;
490 }
491 }
492 else if (mu_tcp_wrapper_enable)
493 {
494 mu_error (_("Rejecting connection from unknown address"));
495 return 1;
496 }
497 }
498
499 /* Reset hup to exit. */
466 signal (SIGHUP, imap4d_signal); 500 signal (SIGHUP, imap4d_signal);
467 /* Timeout alarm. */ 501 /* Timeout alarm. */
468 signal (SIGALRM, imap4d_signal); 502 signal (SIGALRM, imap4d_signal);
469 503
470 util_setio (infile, outfile); 504 util_setio (infile, outfile);
471 505
472 if (debug_mode) 506 if (imap4d_preauth_setup (fd) == 0)
473 { 507 {
474 mu_diag_output (MU_DIAG_INFO, _("Started in debugging mode")); 508 if (debug_mode)
475 text = "IMAP4rev1 Debugging mode"; 509 {
510 mu_diag_output (MU_DIAG_INFO, _("Started in debugging mode"));
511 text = "IMAP4rev1 Debugging mode";
512 }
513 else
514 text = "IMAP4rev1";
476 } 515 }
477 else if (imap4d_preauth_setup (fd) == 0)
478 text = "IMAP4rev1";
479 else 516 else
480 { 517 {
481 util_flush_output (); 518 util_flush_output ();
...@@ -546,7 +583,7 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) ...@@ -546,7 +583,7 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port)
546 mu_diag_output (MU_DIAG_ERROR, "socket: %s", strerror (errno)); 583 mu_diag_output (MU_DIAG_ERROR, "socket: %s", strerror (errno));
547 exit (1); 584 exit (1);
548 } 585 }
549 size = 1; /* Use size here to avoid making a new variable. */ 586 size = 1; /* Use size here to avoid making a new variable. */
550 setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof (size)); 587 setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof (size));
551 size = sizeof (server); 588 size = sizeof (server);
552 memset (&server, 0, size); 589 memset (&server, 0, size);
...@@ -593,10 +630,14 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) ...@@ -593,10 +630,14 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port)
593 else if (pid == 0) /* Child. */ 630 else if (pid == 0) /* Child. */
594 { 631 {
595 int status; 632 int status;
633
596 close (listenfd); 634 close (listenfd);
635
597 status = imap4d_mainloop (connfd, 636 status = imap4d_mainloop (connfd,
598 fdopen (connfd, "r"), 637 fdopen (connfd, "r"),
599 fdopen (connfd, "w")); 638 fdopen (connfd, "w"));
639
640 close (connfd);
600 closelog (); 641 closelog ();
601 exit (status); 642 exit (status);
602 } 643 }
......
...@@ -40,7 +40,7 @@ do_preauth_stdio (struct sockaddr_in *pcs) ...@@ -40,7 +40,7 @@ do_preauth_stdio (struct sockaddr_in *pcs)
40 40
41 "%*[^:]: USERID :%*[^:]:%s" 41 "%*[^:]: USERID :%*[^:]:%s"
42 42
43 returns a malloced copy of the %s part. Otherwise, return NULL. */ 43 returns a mallocked copy of the %s part. Otherwise, return NULL. */
44 44
45 static char * 45 static char *
46 ident_extract_username (char *reply) 46 ident_extract_username (char *reply)
...@@ -440,14 +440,10 @@ imap4d_preauth_setup (int fd) ...@@ -440,14 +440,10 @@ imap4d_preauth_setup (int fd)
440 int len = sizeof cs; 440 int len = sizeof cs;
441 char *username = NULL; 441 char *username = NULL;
442 442
443 mu_diag_output (MU_DIAG_INFO, _("Incoming connection opened"));
444 if (getpeername (fd, (struct sockaddr *) &cs, &len) < 0) 443 if (getpeername (fd, (struct sockaddr *) &cs, &len) < 0)
445 mu_diag_output (MU_DIAG_ERROR, 444 mu_diag_output (MU_DIAG_ERROR,
446 _("Cannot obtain IP address of client: %s"), 445 _("Cannot obtain IP address of client: %s"),
447 strerror (errno)); 446 strerror (errno));
448 else
449 mu_diag_output (MU_DIAG_INFO, _("Connect from %s"),
450 inet_ntoa (cs.sin_addr));
451 447
452 auth_data = NULL; 448 auth_data = NULL;
453 switch (preauth_mode) 449 switch (preauth_mode)
......
...@@ -25,12 +25,14 @@ INCLUDES = @MU_COMMON_INCLUDES@ ...@@ -25,12 +25,14 @@ INCLUDES = @MU_COMMON_INCLUDES@
25 libmuaux_la_SOURCES += \ 25 libmuaux_la_SOURCES += \
26 daemon.c\ 26 daemon.c\
27 mailcap.c\ 27 mailcap.c\
28 mailcap.h\ 28 mu_dbm.c\
29 mu_dbm.c 29 tcpwrap.c
30 30
31 noinst_HEADERS +=\ 31 noinst_HEADERS +=\
32 mailcap.h\
32 mu_dbm.h\ 33 mu_dbm.h\
33 mu_asprintf.h 34 mu_asprintf.h\
35 tcpwrap.h
34 36
35 EXTRA_DIST += utmp.c 37 EXTRA_DIST += utmp.c
36 gl_LIBOBJS += @LIBOBJS@ 38 gl_LIBOBJS += @LIBOBJS@
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007 Free Software Foundation, Inc.
4
5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 GNU Mailutils is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNU Mailutils; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 MA 02110-1301 USA */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23 #include <syslog.h>
24 #include <string.h>
25 #include <mailutils/debug.h>
26 #include <mailutils/nls.h>
27 #include <mailutils/syslog.h>
28 #include <mailutils/cfg.h>
29 #include <mailutils/diag.h>
30
31 int mu_tcp_wrapper_enable = 1;
32 char *mu_tcp_wrapper_daemon;
33
34 #ifdef WITH_LIBWRAP
35 # include <tcpd.h>
36 int deny_severity = LOG_INFO;
37 int allow_severity = LOG_INFO;
38
39 int
40 mu_tcp_wrapper_cb_hosts_allow (mu_debug_t debug, void *data, char *arg)
41 {
42 hosts_allow_table = strdup (arg);
43 return 0;
44 }
45
46 int
47 mu_tcp_wrapper_cb_hosts_deny (mu_debug_t debug, void *data, char *arg)
48 {
49 hosts_deny_table = strdup (arg);
50 return 0;
51 }
52
53 int
54 mu_tcp_wrapper_cb_hosts_allow_syslog (mu_debug_t debug, void *data,
55 char *arg)
56 {
57 if (mu_string_to_syslog_facility (arg, &allow_severity))
58 mu_cfg_format_error (debug, MU_DEBUG_ERROR,
59 _("Unknown syslog facility `%s'"),
60 arg);
61 return 0;
62 }
63
64 int
65 mu_tcp_wrapper_cb_hosts_deny_syslog (mu_debug_t debug, void *data, char *arg)
66 {
67 if (mu_string_to_syslog_facility (arg, &deny_severity))
68 mu_cfg_format_error (debug, MU_DEBUG_ERROR,
69 _("Unknown syslog facility `%s'"),
70 arg);
71 return 0;
72 }
73
74 int
75 mu_tcpwrapper_access (int fd)
76 {
77 struct request_info req;
78
79 if (!mu_tcp_wrapper_enable)
80 return 1;
81 request_init (&req,
82 RQ_DAEMON,
83 mu_tcp_wrapper_daemon ?
84 mu_tcp_wrapper_daemon : mu_program_name,
85 RQ_FILE, fd, NULL);
86 fromhost (&req);
87 return hosts_access (&req);
88 }
89
90 #else
91
92 int
93 mu_tcpwrapper_access (int fd)
94 {
95 return 1;
96 }
97
98 #endif
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007 Free Software Foundation, Inc.
4
5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 GNU Mailutils is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNU Mailutils; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 MA 02110-1301 USA */
19
20 #include <mailutils/types.h>
21
22 extern int mu_tcp_wrapper_enable;
23 const char *mu_tcp_wrapper_daemon;
24 extern int mu_tcp_wrapper_cb_hosts_allow (mu_debug_t debug, void *data,
25 char *arg);
26 extern int mu_tcp_wrapper_cb_hosts_deny (mu_debug_t debug, void *data,
27 char *arg);
28 extern int mu_tcp_wrapper_cb_hosts_allow_syslog (mu_debug_t debug, void *data,
29 char *arg);
30 extern int mu_tcp_wrapper_cb_hosts_deny_syslog (mu_debug_t debug, void *data,
31 char *arg);
32 extern int mu_tcpwrapper_access (int fd);
33
34 #ifdef WITH_LIBWRAP
35 # define TCP_WRAPPERS_CONFIG \
36 { "tcp-wrapper-enable", mu_cfg_bool, &mu_tcp_wrapper_enable, NULL, \
37 N_("Enable TCP wrapper access control. Default is \"yes\".") }, \
38 { "tcp-wrapper-daemon", mu_cfg_string, &mu_tcp_wrapper_daemon, NULL, \
39 N_("Set daemon name for TCP wrapper lookups. Default is program name."), \
40 N_("name") }, \
41 { "hosts-allow-table", mu_cfg_callback, NULL, mu_tcp_wrapper_cb_hosts_allow,\
42 N_("Use file for positive client address access control " \
43 "(default: /etc/hosts.allow)."), \
44 N_("file") }, \
45 { "hosts-deny-table", mu_cfg_callback, NULL, mu_tcp_wrapper_cb_hosts_deny, \
46 N_("Use file for negative client address access control " \
47 "(default: /etc/hosts.deny)."), \
48 N_("file") }, \
49 { "hosts-allow-syslog-level", mu_cfg_callback, NULL, \
50 mu_tcp_wrapper_cb_hosts_allow_syslog, \
51 N_("Log host allows at this syslog level. See logging { facility } for " \
52 "a description of argument syntax."), \
53 N_("level") }, \
54 { "hosts-allow-deny-level", mu_cfg_callback, NULL, \
55 mu_tcp_wrapper_cb_hosts_deny_syslog, \
56 N_("Log host denies at this syslog level. See logging { facility } for " \
57 "a description of argument syntax."), \
58 N_("level") },
59 #else
60 # define TCP_WRAPPERS_CONFIG
61 #endif
...@@ -494,7 +494,9 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -494,7 +494,9 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state)
494 switch (key) 494 switch (key)
495 { 495 {
496 case 'd': 496 case 'd':
497 mu_argp_node_list_new (&lst, "mode", arg); 497 mu_argp_node_list_new (&lst, "mode", "daemon");
498 if (arg)
499 mu_argp_node_list_new (&lst, "max-children", arg);
498 break; 500 break;
499 501
500 case 'i': 502 case 'i':
......
...@@ -43,7 +43,8 @@ maidag_LDADD = \ ...@@ -43,7 +43,8 @@ maidag_LDADD = \
43 ${MU_LIB_MAILER}\ 43 ${MU_LIB_MAILER}\
44 @MU_AUTHLIBS@\ 44 @MU_AUTHLIBS@\
45 ${MU_LIB_MAILUTILS} \ 45 ${MU_LIB_MAILUTILS} \
46 @MU_COMMON_LIBRARIES@ 46 @MU_COMMON_LIBRARIES@\
47 @TCPWRAP_LIBRARIES@
47 48
48 install-exec-hook: 49 install-exec-hook:
49 for i in $(sbin_PROGRAMS); do\ 50 for i in $(sbin_PROGRAMS); do\
......
...@@ -761,8 +761,8 @@ lmtp_loop (FILE *in, FILE *out) ...@@ -761,8 +761,8 @@ lmtp_loop (FILE *in, FILE *out)
761 return 0; 761 return 0;
762 } 762 }
763 763
764 void 764 int
765 log_connection (all_addr_t *addr, socklen_t addrlen) 765 check_connection (int fd, all_addr_t *addr, socklen_t addrlen)
766 { 766 {
767 switch (addr->sa.sa_family) 767 switch (addr->sa.sa_family)
768 { 768 {
...@@ -771,8 +771,16 @@ log_connection (all_addr_t *addr, socklen_t addrlen) ...@@ -771,8 +771,16 @@ log_connection (all_addr_t *addr, socklen_t addrlen)
771 break; 771 break;
772 772
773 case PF_INET: 773 case PF_INET:
774 mu_diag_output (MU_DIAG_INFO, _("connect from %s"), inet_ntoa (addr->s_in.sin_addr)); 774 if (!mu_tcpwrapper_access (fd))
775 {
776 mu_error (_("Access from %s blocked."),
777 inet_ntoa (addr->s_in.sin_addr));
778 return 1;
779 }
780 mu_diag_output (MU_DIAG_INFO, _("connect from %s"),
781 inet_ntoa (addr->s_in.sin_addr));
775 } 782 }
783 return 0;
776 } 784 }
777 785
778 int 786 int
...@@ -837,7 +845,11 @@ lmtp_daemon (char *urlstr) ...@@ -837,7 +845,11 @@ lmtp_daemon (char *urlstr)
837 /*exit (EXIT_FAILURE);*/ 845 /*exit (EXIT_FAILURE);*/
838 } 846 }
839 847
840 log_connection (&addr, addrlen); 848 if (check_connection (connfd, &addr, addrlen))
849 {
850 close (connfd);
851 continue;
852 }
841 853
842 pid = fork (); 854 pid = fork ();
843 if (pid == -1) 855 if (pid == -1)
......
...@@ -179,7 +179,8 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -179,7 +179,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
179 179
180 case LMTP_OPTION: 180 case LMTP_OPTION:
181 mu_argp_node_list_new (&lst, "lmtp", "yes"); 181 mu_argp_node_list_new (&lst, "lmtp", "yes");
182 mu_argp_node_list_new (&lst, "listen", arg); 182 if (arg)
183 mu_argp_node_list_new (&lst, "listen", arg);
183 break; 184 break;
184 185
185 case 'r': 186 case 'r':
...@@ -289,6 +290,7 @@ struct mu_cfg_param maidag_cfg_param[] = { ...@@ -289,6 +290,7 @@ struct mu_cfg_param maidag_cfg_param[] = {
289 N_("url") }, 290 N_("url") },
290 { "reuse-address", mu_cfg_bool, &reuse_lmtp_address, NULL, 291 { "reuse-address", mu_cfg_bool, &reuse_lmtp_address, NULL,
291 N_("Reuse existing address (LMTP mode). Default is \"yes\".") }, 292 N_("Reuse existing address (LMTP mode). Default is \"yes\".") },
293 TCP_WRAPPERS_CONFIG
292 { NULL } 294 { NULL }
293 }; 295 };
294 296
...@@ -453,6 +455,8 @@ main (int argc, char *argv[]) ...@@ -453,6 +455,8 @@ main (int argc, char *argv[])
453 mu_registrar_record (mu_smtp_record); 455 mu_registrar_record (mu_smtp_record);
454 456
455 mu_gocs_register ("sieve", mu_sieve_module_init); 457 mu_gocs_register ("sieve", mu_sieve_module_init);
458
459 mu_gocs_daemon = daemon_param;
456 460
457 /* Parse command line */ 461 /* Parse command line */
458 mu_argp_init (program_version, NULL); 462 mu_argp_init (program_version, NULL);
......
...@@ -93,6 +93,8 @@ ...@@ -93,6 +93,8 @@
93 93
94 #include "mailutils/libargp.h" 94 #include "mailutils/libargp.h"
95 95
96 #include "tcpwrap.h"
97
96 /* Debug */ 98 /* Debug */
97 extern int debug_level; 99 extern int debug_level;
98 #define dbg() if (debug_level) debug 100 #define dbg() if (debug_level) debug
......
...@@ -57,7 +57,7 @@ pop3d_LDADD = \ ...@@ -57,7 +57,7 @@ pop3d_LDADD = \
57 ${MU_LIB_AUTH}\ 57 ${MU_LIB_AUTH}\
58 @MU_AUTHLIBS@ \ 58 @MU_AUTHLIBS@ \
59 ${MU_LIB_MAILUTILS}\ 59 ${MU_LIB_MAILUTILS}\
60 @MU_COMMON_LIBRARIES@ 60 @MU_COMMON_LIBRARIES@ @TCPWRAP_LIBRARIES@
61 61
62 popauth_SOURCES = popauth.c 62 popauth_SOURCES = popauth.c
63 popauth_LDADD = ${MU_APP_LIBRARIES} ${MU_LIB_MAILUTILS} @MU_COMMON_LIBRARIES@ 63 popauth_LDADD = ${MU_APP_LIBRARIES} ${MU_LIB_MAILUTILS} @MU_COMMON_LIBRARIES@
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #include "pop3d.h" 20 #include "pop3d.h"
21 #include "mailutils/pam.h" 21 #include "mailutils/pam.h"
22 #include "mailutils/libargp.h" 22 #include "mailutils/libargp.h"
23 #include "tcpwrap.h"
23 24
24 mu_mailbox_t mbox; 25 mu_mailbox_t mbox;
25 int state; 26 int state;
...@@ -61,7 +62,6 @@ static int pop3d_mainloop (int fd, FILE *, FILE *); ...@@ -61,7 +62,6 @@ static int pop3d_mainloop (int fd, FILE *, FILE *);
61 static void pop3d_daemon_init (void); 62 static void pop3d_daemon_init (void);
62 static void pop3d_daemon (unsigned int, unsigned int); 63 static void pop3d_daemon (unsigned int, unsigned int);
63 static error_t pop3d_parse_opt (int key, char *arg, struct argp_state *astate); 64 static error_t pop3d_parse_opt (int key, char *arg, struct argp_state *astate);
64 static void pop3d_log_connection (int fd);
65 65
66 const char *program_version = "pop3d (" PACKAGE_STRING ")"; 66 const char *program_version = "pop3d (" PACKAGE_STRING ")";
67 static char doc[] = N_("GNU pop3d -- the POP3 daemon"); 67 static char doc[] = N_("GNU pop3d -- the POP3 daemon");
...@@ -159,6 +159,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { ...@@ -159,6 +159,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
159 N_("Set the bulletin database file name."), 159 N_("Set the bulletin database file name."),
160 N_("file") }, 160 N_("file") },
161 #endif 161 #endif
162 TCP_WRAPPERS_CONFIG
162 { NULL } 163 { NULL }
163 }; 164 };
164 165
...@@ -379,26 +380,32 @@ pop3d_daemon_init (void) ...@@ -379,26 +380,32 @@ pop3d_daemon_init (void)
379 #endif 380 #endif
380 } 381 }
381 382
382 void 383 int
383 pop3d_log_connection (int fd) 384 pop3d_get_client_address (int fd, struct sockaddr_in *pcs)
384 { 385 {
385 mu_diag_output (MU_DIAG_INFO, _("Incoming connection opened")); 386 mu_diag_output (MU_DIAG_INFO, _("Incoming connection opened"));
386 387
387 /* log information on the connecting client */ 388 /* log information on the connecting client. */
388 if (debug_mode) 389 if (debug_mode)
389 { 390 {
390 mu_diag_output (MU_DIAG_INFO, _("Started in debugging mode")); 391 mu_diag_output (MU_DIAG_INFO, _("Started in debugging mode"));
392 return 1;
391 } 393 }
392 else 394 else
393 { 395 {
394 struct sockaddr_in cs; 396 int len = sizeof *pcs;
395 int len = sizeof cs; 397 if (getpeername (fd, (struct sockaddr*) pcs, &len) < 0)
396 if (getpeername (fd, (struct sockaddr*)&cs, &len) < 0) 398 {
397 mu_diag_output (MU_DIAG_ERROR, _("Cannot obtain IP address of client: %s"), 399 mu_diag_output (MU_DIAG_ERROR,
398 strerror (errno)); 400 _("Cannot obtain IP address of client: %s"),
401 strerror (errno));
402 return 1;
403 }
399 else 404 else
400 mu_diag_output (MU_DIAG_INFO, _("connect from %s"), inet_ntoa (cs.sin_addr)); 405 mu_diag_output (MU_DIAG_INFO,
406 _("connect from %s"), inet_ntoa (pcs->sin_addr));
401 } 407 }
408 return 0;
402 } 409 }
403 410
404 /* The main part of the daemon. This function reads input from the client and 411 /* The main part of the daemon. This function reads input from the client and
...@@ -412,7 +419,22 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile) ...@@ -412,7 +419,22 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile)
412 { 419 {
413 int status = OK; 420 int status = OK;
414 char buffer[512]; 421 char buffer[512];
422 struct sockaddr_in cs;
415 423
424 if (pop3d_get_client_address (fd, &cs) == 0)
425 {
426 if (!mu_tcpwrapper_access (fd))
427 {
428 mu_error (_("Access from %s blocked."), inet_ntoa (cs.sin_addr));
429 return 1;
430 }
431 }
432 else if (!debug_mode && mu_tcp_wrapper_enable)
433 {
434 mu_error (_("Rejecting connection from unknown address"));
435 return 1;
436 }
437
416 /* Reset hup to exit. */ 438 /* Reset hup to exit. */
417 signal (SIGHUP, pop3d_signal); 439 signal (SIGHUP, pop3d_signal);
418 /* Timeout alarm. */ 440 /* Timeout alarm. */
...@@ -422,8 +444,6 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile) ...@@ -422,8 +444,6 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile)
422 444
423 state = initial_state; 445 state = initial_state;
424 446
425 pop3d_log_connection (fd);
426
427 /* Prepare the shared secret for APOP. */ 447 /* Prepare the shared secret for APOP. */
428 { 448 {
429 char *local_hostname; 449 char *local_hostname;
......