Commit 5f7a34d9 5f7a34d9062b19e0aed1a135d54277aac3aed3f9 by Sergey Poznyakoff

* examples/aclck.c, examples/addr.c, examples/base64.c,

examples/decode2047.c, examples/echosrv.c, examples/encode2047.c,
examples/header.c, examples/http.c, examples/iconv.c,
examples/listop.c, examples/lsf.c, examples/mailcap.c,
examples/mimetest.c, examples/msg-send.c, examples/muemail.c,
examples/murun.c, examples/nntpclient.c, examples/pop3client.c,
examples/sfrom.c, examples/url-parse.c: Include config.h. Use
MU_ASSERT instead of assert.

* include/mailutils/cfg.h (struct mu_cfg_section.offset): New
member.
* include/mailutils/debug.hm4 (MU_ASSERT): New member.
* lib/utmp.c: Include config.h.
* libcfg/Makefile.am (libmucfg_la_SOURCES): Add acl.c.
* libcfg/acl.c: New file.
* libcfg/common.c (cb_debug_level): Immediately set debugging
level.
* mailbox/acl.c: mu_acl_log expands its argument.
* mailbox/cfg_driver.c (mu_create_canned_section)
(mu_create_canned_param): Avoid creating container twice.
* mailbox/cfg_format.c (format_param): Do not pring type if
argname contains a colon.
* mailbox/cfg_parser.y (_scan_tree_helper): Compute target
pointer.

* imap4d/imap4d.c, imap4d/imap4d.h, pop3d/pop3d.c,
pop3d/pop3d.h: Use MU ACLs
1 parent 95a3987b
2007-12-13 Sergey Poznyakoff <gray@gnu.org.ua>
* examples/aclck.c, examples/addr.c, examples/base64.c,
examples/decode2047.c, examples/echosrv.c, examples/encode2047.c,
examples/header.c, examples/http.c, examples/iconv.c,
examples/listop.c, examples/lsf.c, examples/mailcap.c,
examples/mimetest.c, examples/msg-send.c, examples/muemail.c,
examples/murun.c, examples/nntpclient.c, examples/pop3client.c,
examples/sfrom.c, examples/url-parse.c: Include config.h. Use
MU_ASSERT instead of assert.
* include/mailutils/cfg.h (struct mu_cfg_section.offset): New
member.
* include/mailutils/debug.hm4 (MU_ASSERT): New member.
* lib/utmp.c: Include config.h.
* libcfg/Makefile.am (libmucfg_la_SOURCES): Add acl.c.
* libcfg/acl.c: New file.
* libcfg/common.c (cb_debug_level): Immediately set debugging
level.
* mailbox/acl.c: mu_acl_log expands its argument.
* mailbox/cfg_driver.c (mu_create_canned_section)
(mu_create_canned_param): Avoid creating container twice.
* mailbox/cfg_format.c (format_param): Do not pring type if
argname contains a colon.
* mailbox/cfg_parser.y (_scan_tree_helper): Compute target
pointer.
* imap4d/imap4d.c, imap4d/imap4d.h, pop3d/pop3d.c,
pop3d/pop3d.h: Use MU ACLs
2007-12-11 Sergey Poznyakoff <gray@gnu.org.ua>
* comsat/comsat.c, imap4d/imap4d.c, maidag/maidag.c,
......
......@@ -17,6 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/mailutils.h>
#include <sys/socket.h>
......
......@@ -17,6 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
......
......@@ -17,6 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
......@@ -78,19 +81,18 @@ main (int argc, char * argv [])
}
if (input)
c = mu_file_stream_create (&in, input, MU_STREAM_READ);
MU_ASSERT (mu_file_stream_create (&in, input, MU_STREAM_READ));
else
c = mu_stdio_stream_create (&in, stdin, 0);
assert (c == 0);
assert (mu_filter_create (&flt, in, encoding, mode, MU_STREAM_READ) == 0);
assert (mu_stream_open (in) == 0);
MU_ASSERT (mu_stdio_stream_create (&in, stdin, 0));
MU_ASSERT (mu_filter_create (&flt, in, encoding, mode, MU_STREAM_READ));
MU_ASSERT (mu_stream_open (in));
if (output)
c = mu_file_stream_create (&out, output, MU_STREAM_WRITE|MU_STREAM_CREAT);
MU_ASSERT (mu_file_stream_create (&out, output,
MU_STREAM_WRITE|MU_STREAM_CREAT));
else
c = mu_stdio_stream_create (&out, stdout, 0);
assert (c == 0);
assert (mu_stream_open (out) == 0);
MU_ASSERT (mu_stdio_stream_create (&out, stdout, 0));
MU_ASSERT (mu_stream_open (out));
while (mu_stream_read (flt, &buffer, sizeof (buffer), total, &size) == 0
&& size > 0)
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
......
......@@ -32,18 +32,6 @@
#include <mailutils/mailutils.h>
#include <mailutils/server.h>
#define MU_ASSERT(expr) \
do \
{ \
int rc = expr; \
if (rc) \
{ \
mu_error (#expr " failed: %s", mu_strerror (rc)); \
abort (); \
} \
} \
while (0);
mu_server_t server;
int
......@@ -52,8 +40,7 @@ echo_conn (int fd, struct sockaddr_in *s, void *server_data, void *call_data,
{
struct sockaddr_in srv_addr;
pid_t pid;
char *buf = NULL;
size_t size = 0;
char buf[512];
FILE *in, *out;
mu_tcp_server_get_sockaddr (srv, &srv_addr);
......@@ -82,10 +69,10 @@ echo_conn (int fd, struct sockaddr_in *s, void *server_data, void *call_data,
setvbuf (out, NULL, _IOLBF, 0);
pid = getpid ();
while (getline (&buf, &size, in) > 0)
while (fgets (buf, sizeof (buf), in) > 0)
{
int len = strlen (buf);
if (len > 0)
if (len > 0 && buf[len-1] == '\n')
{
buf[--len] = 0;
if (buf[len-1] == '\r')
......@@ -93,7 +80,6 @@ echo_conn (int fd, struct sockaddr_in *s, void *server_data, void *call_data,
}
fprintf (out, "%lu: you said: \"%s\"\r\n", (unsigned long) pid, buf);
}
free (buf);
exit (0);
}
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
......
......@@ -20,6 +20,9 @@
It connects to a remote HTTP server and prints the contents of its
index page */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......
......@@ -16,12 +16,14 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <mailutils/mailutils.h>
......@@ -40,15 +42,14 @@ main (int argc, char **argv)
return 1;
}
rc = mu_stdio_stream_create (&in, stdin, 0);
assert (rc == 0);
assert (mu_stream_open (in) == 0);
assert (mu_filter_iconv_create (&cvt, in, argv[1], argv[2], 0, mu_fallback_none) == 0);
assert (mu_stream_open (cvt) == 0);
MU_ASSERT (mu_stdio_stream_create (&in, stdin, 0));
MU_ASSERT (mu_stream_open (in));
MU_ASSERT (mu_filter_iconv_create (&cvt, in, argv[1], argv[2],
0, mu_fallback_none));
MU_ASSERT (mu_stream_open (cvt));
rc = mu_stdio_stream_create (&out, stdout, 0);
assert (rc == 0);
assert (mu_stream_open (out) == 0);
MU_ASSERT (mu_stdio_stream_create (&out, stdout, 0));
MU_ASSERT (mu_stream_open (out));
while ((rc = mu_stream_read (cvt, buffer, sizeof (buffer), total, &size)) == 0
&& size > 0)
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
......
......@@ -16,21 +16,14 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/mailutils.h>
#define C(X) do \
{ \
int e; \
if ((e = X) != 0) \
{ \
mu_error ("%s failed: %s\n", #X, mu_strerror (e)); \
return 1; \
} \
} while (0)
static int
ls_printer (void *item, void *data)
{
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <mailutils/mailcap.h>
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -52,18 +55,6 @@ print_file (const char *fname, int indent)
unlink (fname);
}
#define CATCH(expr) \
do \
{ \
int rc; \
if ((rc = expr) != 0) \
{ \
fprintf (stderr, "%s: %s\n", #expr, mu_strerror (rc)); \
exit (2); \
} \
} \
while (0)
int
main (int argc, char **argv)
{
......@@ -93,7 +84,7 @@ main (int argc, char **argv)
mu_registrar_record (mu_path_record);
mu_registrar_record (mu_pop_record);
CATCH (mu_mailbox_create_default (&mbox, mailbox_name));
MU_ASSERT (mu_mailbox_create_default (&mbox, mailbox_name));
/* Debugging trace. */
if (debug)
......@@ -104,7 +95,7 @@ main (int argc, char **argv)
}
/* Open the mailbox for reading only. */
CATCH (mu_mailbox_open (mbox, MU_STREAM_RDWR));
MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_RDWR));
/* Iterate through the entire message set. */
mu_mailbox_messages_count (mbox, &count);
......@@ -116,10 +107,10 @@ main (int argc, char **argv)
size_t nparts;
size_t msize, nlines;
CATCH (mu_mailbox_get_message (mbox, i, &msg));
CATCH (mu_message_size (msg, &msize));
CATCH (mu_message_lines (msg, &nlines));
CATCH (mu_message_get_header (msg, &hdr));
MU_ASSERT (mu_mailbox_get_message (mbox, i, &msg));
MU_ASSERT (mu_message_size (msg, &msize));
MU_ASSERT (mu_message_lines (msg, &nlines));
MU_ASSERT (mu_message_get_header (msg, &hdr));
if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from))
from = "";
if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject))
......@@ -128,7 +119,7 @@ main (int argc, char **argv)
printf ("From: %s\n", from);
printf ("Subject: %s\n", subject);
CATCH (mu_message_get_num_parts (msg, &nparts));
MU_ASSERT (mu_message_get_num_parts (msg, &nparts));
printf ("Number of parts in message - %lu\n",
(unsigned long) nparts);
printf ("Total message size - %lu/%lu\n",
......@@ -149,14 +140,14 @@ print_message_part_sizes (mu_message_t part, int indent)
mu_header_t hdr;
size_t msize, mlines, hsize, hlines, bsize, blines;
CATCH (mu_message_size (part, &msize));
CATCH (mu_message_lines (part, &mlines));
CATCH (mu_message_get_header (part, &hdr));
CATCH (mu_header_size (hdr, &hsize));
CATCH (mu_header_lines (hdr, &hlines));
CATCH (mu_message_get_body (part, &body));
CATCH (mu_body_size (body, &bsize));
CATCH (mu_body_lines (body, &blines));
MU_ASSERT (mu_message_size (part, &msize));
MU_ASSERT (mu_message_lines (part, &mlines));
MU_ASSERT (mu_message_get_header (part, &hdr));
MU_ASSERT (mu_header_size (hdr, &hsize));
MU_ASSERT (mu_header_lines (hdr, &hlines));
MU_ASSERT (mu_message_get_body (part, &body));
MU_ASSERT (mu_body_size (body, &bsize));
MU_ASSERT (mu_body_lines (body, &blines));
printf ("%*.*sMessage part size - %lu/%lu: %lu/%lu, %lu/%lu\n",
indent, indent, "",
(unsigned long) msize, (unsigned long) mlines,
......@@ -191,8 +182,8 @@ message_display_parts (mu_message_t msg, int indent)
for (j = 1; j <= nparts; j++)
{
int status;
CATCH (mu_message_get_part (msg, j, &part));
CATCH (mu_message_get_header (part, &hdr));
MU_ASSERT (mu_message_get_part (msg, j, &part));
MU_ASSERT (mu_message_get_header (part, &hdr));
status = mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &type);
if (status == MU_ERR_NOENT)
type = "";
......@@ -212,9 +203,9 @@ message_display_parts (mu_message_t msg, int indent)
|| (mu_message_is_multipart (part, &ismulti) == 0 && ismulti))
{
if (!ismulti)
CATCH (mu_message_unencapsulate (part, &part, NULL));
MU_ASSERT (mu_message_unencapsulate (part, &part, NULL));
CATCH (mu_message_get_header (part, &hdr));
MU_ASSERT (mu_message_get_header (part, &hdr));
if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from))
from = "";
if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject))
......@@ -222,7 +213,7 @@ message_display_parts (mu_message_t msg, int indent)
printf ("%*.*sEncapsulated message : %s\t%s\n",
indent, indent, "", from, subject);
printf ("%*.*sBegin\n", indent, indent, "");
CATCH (mu_message_get_num_parts (part, &nsubparts));
MU_ASSERT (mu_message_get_num_parts (part, &nsubparts));
message_display_parts (part, indent+indent_level);
mu_message_destroy (&part, NULL);
}
......
......@@ -16,6 +16,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
......@@ -34,14 +38,6 @@
#include <mailutils/registrar.h>
#include <mailutils/stream.h>
#define C(X) do {\
int e;\
if((e = X) != 0) { \
fprintf(stderr, "%s failed: %s\n", #X, mu_strerror(e)); \
exit(1);\
}\
} while (0)
const char USAGE[] =
"usage: mailer [-hd] [-m mailer] [-f from] [to]..."
;
......@@ -101,21 +97,21 @@ main (int argc, char *argv[])
if (optfrom)
{
C (mu_address_create (&from, optfrom));
MU_ASSERT (mu_address_create (&from, optfrom));
}
if (argv[optind])
{
char **av = argv + optind;
C (mu_address_createv (&to, (const char **) av, -1));
MU_ASSERT (mu_address_createv (&to, (const char **) av, -1));
}
C (mu_stdio_stream_create (&in, stdin, MU_STREAM_SEEKABLE));
C (mu_stream_open (in));
C (mu_message_create (&msg, NULL));
C (mu_message_set_stream (msg, in, NULL));
C (mu_mailer_create (&mailer, optmailer));
MU_ASSERT (mu_stdio_stream_create (&in, stdin, MU_STREAM_SEEKABLE));
MU_ASSERT (mu_stream_open (in));
MU_ASSERT (mu_message_create (&msg, NULL));
MU_ASSERT (mu_message_set_stream (msg, in, NULL));
MU_ASSERT (mu_mailer_create (&mailer, optmailer));
if (optdebug)
{
......@@ -124,9 +120,9 @@ main (int argc, char *argv[])
mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT));
}
C (mu_mailer_open (mailer, 0));
MU_ASSERT (mu_mailer_open (mailer, 0));
C (mu_mailer_send_message (mailer, msg, from, to));
MU_ASSERT (mu_mailer_send_message (mailer, msg, from, to));
return 0;
}
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <mailutils/mutil.h>
......
......@@ -16,11 +16,13 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <mailutils/mailutils.h>
......@@ -62,12 +64,12 @@ main (int argc, char *argv[])
exit (1);
}
assert (mu_argcv_string (argc - i, &argv[i], &cmdline) == 0);
MU_ASSERT (mu_argcv_string (argc - i, &argv[i], &cmdline));
if (read_stdin)
{
mu_stream_t in;
assert (mu_stdio_stream_create (&in, stdin, 0) == 0);
assert (mu_stream_open (in) == 0);
MU_ASSERT (mu_stdio_stream_create (&in, stdin, 0));
MU_ASSERT (mu_stream_open (in));
rc = mu_filter_prog_stream_create (&stream, cmdline, in);
}
else
......@@ -87,9 +89,8 @@ main (int argc, char *argv[])
exit (1);
}
assert (mu_stdio_stream_create (&out, stdout, 0) == 0);
assert (rc == 0);
assert (mu_stream_open (out) == 0);
MU_ASSERT (mu_stdio_stream_create (&out, stdout, 0));
MU_ASSERT (mu_stream_open (out));
read_and_print (stream, out);
mu_stream_close (stream);
......
......@@ -20,7 +20,7 @@
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h> /* For MU_ARG_UNUSED only */
# include <config.h>
#endif
#include <sys/types.h>
#include <unistd.h>
......
......@@ -20,7 +20,7 @@
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h> /* For MU_ARG_UNUSED only */
# include <config.h>
#endif
#include <sys/types.h>
#include <unistd.h>
......
......@@ -17,6 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......
......@@ -16,6 +16,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
......
......@@ -51,6 +51,8 @@ int ident_port;
char *ident_keyfile;
int ident_encrypt_only;
mu_acl_t imap4d_acl;
/* Number of child processes. */
size_t children;
......@@ -300,10 +302,11 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
N_("Name of DES keyfile for decoding ecrypted ident responses.") },
{ "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, 0, NULL,
N_("Use only encrypted ident responses.") },
{ "acl", mu_cfg_section, },
TCP_WRAPPERS_CONFIG
{ NULL }
};
int
main (int argc, char **argv)
{
......@@ -325,9 +328,10 @@ main (int argc, char **argv)
mu_gocs_register ("gsasl", mu_gsasl_module_init);
#endif
mu_tcpwrapper_cfg_init ();
mu_acl_cfg_init ();
mu_argp_init (program_version, NULL);
if (mu_app_init (&argp, imap4d_capa, imap4d_cfg_param,
argc, argv, 0, NULL, NULL))
argc, argv, 0, NULL, &imap4d_acl))
exit (1);
if (login_disabled)
......@@ -397,6 +401,13 @@ main (int argc, char **argv)
mu_diag_get_debug (&debug);
mu_debug_set_print (debug, mu_diag_syslog_printer, NULL);
/* FIXME: this should be done automatically by cfg */
if (imap4d_acl)
{
mu_acl_get_debug (imap4d_acl, &debug);
mu_debug_set_print (debug, mu_debug_syslog_printer, NULL);
}
}
umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */
......@@ -466,9 +477,6 @@ get_client_address (int fd, struct sockaddr_in *pcs)
strerror (errno));
return 1;
}
mu_diag_output (MU_DIAG_INFO, _("Connect from %s"),
inet_ntoa (pcs->sin_addr));
return 0;
}
......@@ -484,13 +492,44 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
{
if (get_client_address (fd, &cs) == 0)
{
if (imap4d_acl)
{
mu_acl_result_t res;
int rc = mu_acl_check_sockaddr (imap4d_acl,
(struct sockaddr*) &cs,
sizeof (cs),
&res);
if (rc)
{
mu_error (_("Access from %s blocked: cannot check ACLs: %s"),
inet_ntoa (cs.sin_addr), mu_strerror (rc));
return 1;
}
switch (res)
{
case mu_acl_result_undefined:
mu_diag_output (MU_DIAG_INFO,
_("%s: undefined ACL result; access allowed"),
inet_ntoa (cs.sin_addr));
break;
case mu_acl_result_accept:
break;
case mu_acl_result_deny:
mu_error (_("Access from %s blocked."),
inet_ntoa (cs.sin_addr));
return 1;
}
}
if (!mu_tcpwrapper_access (fd))
{
mu_error (_("Access from %s blocked."), inet_ntoa (cs.sin_addr));
return 1;
}
}
else if (mu_tcp_wrapper_enable)
else if (mu_tcp_wrapper_enable || imap4d_acl)
{
mu_error (_("Rejecting connection from unknown address"));
return 1;
......
......@@ -96,6 +96,7 @@
#include <mailutils/url.h>
#include <mailutils/daemon.h>
#include <mailutils/pam.h>
#include <mailutils/acl.h>
#include <mu_asprintf.h>
#include <mu_umaxtostr.h>
......
......@@ -159,6 +159,7 @@ struct mu_cfg_section
char *label;
mu_cfg_section_fp parser;
void *target;
size_t offset;
mu_list_t /* of mu_cfg_cont */ children;
char *docstring;
};
......
......@@ -92,6 +92,21 @@ int mu_global_debug_from_string (const char *, const char *);
int mu_debug_level_from_string (const char *string, mu_log_level_t *plev,
mu_debug_t debug);
#define MU_ASSERT(expr) \
do \
{ \
int rc = expr; \
if (rc) \
{ \
mu_error ("%s:%d: " #expr " failed: %s", \
__FILE__, __LINE__, mu_strerror (rc)); \
abort (); \
} \
} \
while (0)
forloop(`i',1,11,`MKDEBUG(i)')
#ifdef __cplusplus
......
......@@ -17,6 +17,9 @@ Licensealong with this program; if not, write to the Free
SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <utmp.h>
......
......@@ -22,6 +22,7 @@ AM_CFLAGS = -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\" \
lib_LTLIBRARIES = libmucfg.la
libmucfg_la_SOURCES=\
acl.c\
auth.c\
common.c\
init.c\
......
/* This file is part of GNU Mailutils
Copyright (C) 2007 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailutils/libcfg.h"
#include "mailutils/acl.h"
#include "mailutils/argcv.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define ISSPACE(c) ((c)==' '||(c)=='\t')
#define SKIPWS(p) while (*(p) && ISSPACE (*(p))) (p)++;
static char *
getword (char **parg)
{
char *arg = *parg;
char *word;
SKIPWS (arg);
word = arg;
if (*arg)
{
while (*arg && !ISSPACE (*arg))
arg++;
*arg++ = 0;
}
*parg = arg;
return word;
}
struct netdef
{
struct sockaddr *sa;
int len;
unsigned long netmask;
};
#ifndef INADDR_ANY
# define INADDR_ANY 0
#endif
int
parse_address (mu_debug_t err, char *str, struct netdef *nd)
{
struct sockaddr_in in;
in.sin_family = AF_INET;
if (strcmp (str, "any") == 0)
{
in.sin_addr.s_addr = INADDR_ANY;
nd->netmask = 0;
}
else if (inet_aton (str, &in.sin_addr) == 0)
{
mu_cfg_format_error (err, MU_DEBUG_ERROR, _("Invalid IPv4: %s"), str);
return 1;
}
in.sin_port = 0;
nd->len = sizeof (in);
nd->sa = malloc (nd->len);
if (!nd->sa)
{
mu_cfg_format_error (err, MU_DEBUG_ERROR, "%s", mu_strerror (errno));
return 1;
}
memcpy (nd->sa, &in, sizeof (in));
return 0;
}
static int
parsearg (mu_debug_t err, char *arg, struct netdef *pnd, char **prest)
{
char *w, *p;
unsigned long netmask;
w = getword (&arg);
if (strcmp (w, "from") == 0)
w = getword (&arg);
p = strchr (w, '/');
if (p)
{
char *q;
unsigned netlen;
*p++ = 0;
netlen = strtoul (p, &q, 10);
if (*q == 0)
{
if (netlen == 0)
netmask = 0;
else
{
netmask = 0xfffffffful >> (32 - netlen);
netmask <<= (32 - netlen);
netmask = htonl (netmask);
}
}
else if (*q == '.')
{
struct in_addr addr;
if (inet_aton (p, &addr) == 0)
{
mu_cfg_format_error (err, MU_DEBUG_ERROR, _("invalid netmask"));
return 1;
}
netmask = addr.s_addr;
}
else
{
mu_cfg_format_error (err, MU_DEBUG_ERROR, _("invalid netmask"));
return 1;
}
}
else
netmask = 0xfffffffful;
pnd->netmask = netmask;
if (parse_address (err, w, pnd))
return 1;
SKIPWS (arg);
if (prest)
{
if (*arg == 0)
*prest = NULL;
else
{
int len = strlen (arg);
*prest = malloc (len);
if (!prest)
{
mu_cfg_format_error (err, MU_DEBUG_ERROR,
"%s", mu_strerror (errno));
return 1;
}
if (arg[0] == '"' || arg[0] == '\'')
mu_argcv_unquote_copy (*prest, arg, len);
else
strcpy (*prest, arg);
}
}
else if (*arg != 0)
{
mu_cfg_format_error (err, MU_DEBUG_ERROR, _("junk after IP address"));
return 1;
}
return 0;
}
static int
cb_allow (mu_debug_t err, void *data, char *arg)
{
int rc;
mu_acl_t acl = *(mu_acl_t*)data;
struct netdef ndef;
if (parsearg (err, arg, &ndef, NULL))
return 1;
rc = mu_acl_append (acl, mu_acl_accept, NULL, ndef.sa, ndef.len,
ndef.netmask);
if (rc)
mu_cfg_format_error (err, MU_DEBUG_ERROR,
_("cannot append acl entry: %s"),
mu_strerror (rc));
free (ndef.sa);
return rc;
}
static int
cb_deny (mu_debug_t err, void *data, char *arg)
{
int rc;
mu_acl_t acl = *(mu_acl_t*)data;
struct netdef ndef;
if (parsearg (err, arg, &ndef, NULL))
return 1;
rc = mu_acl_append (acl, mu_acl_deny, NULL, ndef.sa, ndef.len,
ndef.netmask);
if (rc)
mu_cfg_format_error (err, MU_DEBUG_ERROR,
_("cannot append acl entry: %s"),
mu_strerror (rc));
free (ndef.sa);
return rc;
}
static int
cb_log (mu_debug_t err, void *data, char *arg)
{
int rc;
mu_acl_t acl = *(mu_acl_t*)data;
struct netdef ndef;
char *rest;
if (parsearg (err, arg, &ndef, &rest))
return 1;
rc = mu_acl_append (acl, mu_acl_log, rest, ndef.sa, ndef.len,
ndef.netmask);
if (rc)
mu_cfg_format_error (err, MU_DEBUG_ERROR,
_("cannot append acl entry: %s"),
mu_strerror (rc));
free (ndef.sa);
return rc;
}
static int
cb_exec (mu_debug_t err, void *data, char *arg)
{
int rc;
mu_acl_t acl = *(mu_acl_t*)data;
struct netdef ndef;
char *rest;
if (parsearg (err, arg, &ndef, &rest))
return 1;
rc = mu_acl_append (acl, mu_acl_exec, rest, ndef.sa, ndef.len,
ndef.netmask);
if (rc)
mu_cfg_format_error (err, MU_DEBUG_ERROR,
_("cannot append acl entry: %s"),
mu_strerror (rc));
free (ndef.sa);
return rc;
}
static int
cb_ifexec (mu_debug_t err, void *data, char *arg)
{
int rc;
mu_acl_t acl = *(mu_acl_t*)data;
struct netdef ndef;
char *rest;
if (parsearg (err, arg, &ndef, &rest))
return 1;
rc = mu_acl_append (acl, mu_acl_ifexec, rest, ndef.sa, ndef.len,
ndef.netmask);
if (rc)
mu_cfg_format_error (err, MU_DEBUG_ERROR,
_("cannot append acl entry: %s"),
mu_strerror (rc));
free (ndef.sa);
return rc;
}
static struct mu_cfg_param acl_param[] = {
{ "allow", mu_cfg_callback, NULL, 0, cb_allow,
N_("Allow connections from this IP address. Optional word `from' is "
"allowed between it and its argument. The same holds true for other "
"actions below."),
N_("addr: IP") },
{ "deny", mu_cfg_callback, NULL, 0, cb_deny,
N_("Deny connections from this IP address."),
N_("addr: IP") },
{ "log", mu_cfg_callback, NULL, 0, cb_log,
N_("Log connections from this IP address."),
N_("addr: IP") },
{ "exec", mu_cfg_callback, NULL, 0, cb_exec,
N_("Execute supplied program if a connection from this IP address is "
"requested. Arguments are:\n"
" <addr: IP> <program: string>\n"
"Following macros are expanded in <program> before executing:\n"
" address - Source IP address\n"
" port - Source port number\n") },
{ "ifexec", mu_cfg_callback, NULL, 0, cb_ifexec,
N_("If a connection from this IP address is requested, execute supplied "
"program and allow or deny the connection depending on its exit code. "
"See `exec' for a description of its arguments.") },
{ NULL }
};
static int
acl_section_parser (enum mu_cfg_section_stage stage,
const mu_cfg_node_t *node,
const char *section_label, void **section_data,
void *call_data,
mu_cfg_tree_t *tree)
{
switch (stage)
{
case mu_cfg_section_start:
{
void *data = *section_data;
mu_acl_create ((mu_acl_t*)data);
}
break;
case mu_cfg_section_end:
break;
}
return 0;
}
void
mu_acl_cfg_init ()
{
struct mu_cfg_section *section;
if (mu_create_canned_section ("acl", &section) == 0)
{
section->parser = acl_section_parser;
mu_cfg_section_add_params (section, acl_param);
}
}
......@@ -232,7 +232,11 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg)
}
else
pfx = strdup ("command line");/*FIXME*/
debug_settings.errpfx = pfx;
/*FIXME:*/
mu_global_debug_from_string (debug_settings.string, pfx);
free (debug_settings.string);
free (debug_settings.errpfx);
memset (&debug_settings, 0, sizeof debug_settings);
return 0;
}
......
......@@ -426,11 +426,10 @@ _expand_aclno (const char *name, void *data, char **p)
#endif
static int
spawn_prog (const char *cmdline, int *pstatus, struct run_closure *rp)
expand_arg (const char *cmdline, struct run_closure *rp, char **s)
{
char *s;
int rc;
mu_vartab_t vtab;
pid_t pid;
MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "Expanding \"%s\" => ", cmdline);
......@@ -463,10 +462,24 @@ spawn_prog (const char *cmdline, int *pstatus, struct run_closure *rp)
break;
}
mu_vartab_expand (vtab, cmdline, &s);
rc = mu_vartab_expand (vtab, cmdline, s);
mu_vartab_destroy (&vtab);
MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "\"%s\". ", s);
if (rc == 0)
MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "\"%s\". ", *s);
else
MU_DEBUG (rp->debug, MU_DEBUG_TRACE0, "failed. ");
return rc;
}
static int
spawn_prog (const char *cmdline, int *pstatus, struct run_closure *rp)
{
char *s;
pid_t pid;
if (expand_arg (cmdline, rp, &s))
s = strdup (cmdline);
pid = fork ();
if (pid == 0)
......@@ -549,12 +562,19 @@ _run_entry (void *item, void *data)
case mu_acl_log:
{
char *s;
mu_debug_t dbg = NULL;
mu_diag_get_debug (&dbg);
debug_sockaddr (dbg, MU_DIAG_INFO, rp->sa);
if (ent->arg)
mu_debug_printf (dbg, MU_DIAG_INFO, ": %s", (char*) ent->arg);
mu_debug_printf (dbg, MU_DIAG_INFO, "\n");
if (ent->arg && expand_arg (ent->arg, rp, &s) == 0)
{
mu_debug_printf (dbg, MU_DIAG_INFO, "%s\n", s);
free (s);
}
else
{
debug_sockaddr (dbg, MU_DIAG_INFO, rp->sa);
mu_debug_printf (dbg, MU_DIAG_INFO, "\n");
}
}
break;
......
......@@ -56,12 +56,14 @@ mu_create_canned_section (char *name, struct mu_cfg_section **psection)
struct mu_cfg_cont **pcont;
alloc_section_tab ();
rc = mu_assoc_ref_install (section_tab, name, (void **)&pcont);
if (rc == 0 || rc == MU_ERR_EXISTS)
if (rc == 0)
{
mu_config_create_container (pcont, mu_cfg_cont_section);
*psection = &(*pcont)->v.section;
(*psection)->ident = name;
}
else if (rc == MU_ERR_EXISTS)
*psection = &(*pcont)->v.section;
return rc;
}
......@@ -72,12 +74,14 @@ mu_create_canned_param (char *name, struct mu_cfg_param **pparam)
struct mu_cfg_cont **pcont;
alloc_section_tab ();
rc = mu_assoc_ref_install (section_tab, name, (void **)&pcont);
if (rc == 0 || rc == MU_ERR_EXISTS)
if (rc == 0)
{
mu_config_create_container (pcont, mu_cfg_cont_param);
*pparam = &(*pcont)->v.param;
(*pparam)->ident = name;
}
else if (rc == MU_ERR_EXISTS)
*pparam = &(*pcont)->v.param;
return rc;
}
......@@ -256,6 +260,7 @@ mu_cfg_section_add_params (struct mu_cfg_section *sect,
abort ();
}
mu_config_clone_container (container);
container->v.section.offset = param->offset;
}
else
{
......
......@@ -234,11 +234,16 @@ format_param (mu_stream_t stream, struct mu_cfg_param *param, int level)
if (param->docstring)
mu_cfg_format_docstring (stream, gettext (param->docstring), level);
format_level (stream, level);
mu_stream_sequential_printf (stream, "%s <%s: %s>;\n",
param->ident,
gettext (param->argname ?
param->argname : N_("arg")),
gettext (mu_cfg_data_type_string (param->type)));
if (param->argname && strchr (param->argname, ':'))
mu_stream_sequential_printf (stream, "%s <%s>;\n",
param->ident,
gettext (param->argname));
else
mu_stream_sequential_printf (stream, "%s <%s: %s>;\n",
param->ident,
gettext (param->argname ?
param->argname : N_("arg")),
gettext (mu_cfg_data_type_string (param->type)));
}
static void format_container (mu_stream_t stream, struct mu_cfg_cont *cont,
......
......@@ -999,6 +999,10 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
}
if (!sec->children)
return MU_CFG_ITER_SKIP;
if (sdata->list->sec->target)
sec->target = (char*)sdata->list->sec->target + sec->offset;
else if (sdata->target)
sec->target = (char*)sdata->target + sec->offset;
if (sec->parser &&
sec->parser (mu_cfg_section_start, node,
sec->label, &sec->target,
......
......@@ -58,6 +58,8 @@ char *login_stat_file = LOGIN_STAT_FILE;
unsigned expire = EXPIRE_NEVER; /* Expire messages after this number of days */
int expire_on_exit = 0; /* Delete expired messages on exit */
mu_acl_t pop3d_acl;
static int pop3d_mainloop (int fd, FILE *, FILE *);
static void pop3d_daemon_init (void);
static void pop3d_daemon (unsigned int, unsigned int);
......@@ -261,11 +263,12 @@ main (int argc, char **argv)
mu_gocs_register ("tls", mu_tls_module_init);
#endif /* WITH_TLS */
mu_tcpwrapper_cfg_init ();
mu_acl_cfg_init ();
mu_gocs_daemon = default_gocs_daemon;
mu_argp_init (program_version, NULL);
if (mu_app_init (&argp, pop3d_argp_capa, pop3d_cfg_param,
argc, argv, 0, NULL, NULL))
argc, argv, 0, NULL, &pop3d_acl))
exit (1);
if (expire == 0)
......@@ -326,6 +329,13 @@ main (int argc, char **argv)
mu_diag_get_debug (&debug);
mu_debug_set_print (debug, mu_diag_syslog_printer, NULL);
/* FIXME: this should be done automatically by cfg */
if (pop3d_acl)
{
mu_acl_get_debug (pop3d_acl, &debug);
mu_debug_set_print (debug, mu_debug_syslog_printer, NULL);
}
}
umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */
......@@ -403,9 +413,6 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs)
strerror (errno));
return 1;
}
else
mu_diag_output (MU_DIAG_INFO,
_("connect from %s"), inet_ntoa (pcs->sin_addr));
}
return 0;
}
......@@ -425,13 +432,44 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile)
if (pop3d_get_client_address (fd, &cs) == 0)
{
if (pop3d_acl)
{
mu_acl_result_t res;
int rc = mu_acl_check_sockaddr (pop3d_acl,
(struct sockaddr*) &cs,
sizeof (cs),
&res);
if (rc)
{
mu_error (_("Access from %s blocked: cannot check ACLs: %s"),
inet_ntoa (cs.sin_addr), mu_strerror (rc));
return 1;
}
switch (res)
{
case mu_acl_result_undefined:
mu_diag_output (MU_DIAG_INFO,
_("%s: undefined ACL result; access allowed"),
inet_ntoa (cs.sin_addr));
break;
case mu_acl_result_accept:
break;
case mu_acl_result_deny:
mu_error (_("Access from %s blocked."),
inet_ntoa (cs.sin_addr));
return 1;
}
}
if (!mu_tcpwrapper_access (fd))
{
mu_error (_("Access from %s blocked."), inet_ntoa (cs.sin_addr));
return 1;
}
}
else if (!debug_mode && mu_tcp_wrapper_enable)
else if (!debug_mode && (mu_tcp_wrapper_enable || pop3d_acl))
{
mu_error (_("Rejecting connection from unknown address"));
return 1;
......
......@@ -155,6 +155,7 @@ extern int expire_on_exit;
#include <mailutils/tls.h>
#include <mailutils/url.h>
#include <mailutils/md5.h>
#include <mailutils/acl.h>
/* For Berkley DB2 APOP password file */
#ifdef HAVE_DB_H
......