diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-30 01:46:32 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-30 01:46:32 +0000 |
commit | 643be57eb09fe6485ccc8f4cf3ac9a592c207bb5 (patch) | |
tree | e8a10fd3b2586821f951b8c8eeff6ad7f87818e3 | |
parent | b7e41daa82b7ed40c06c6a01cd502fa409f836c3 (diff) | |
download | mailutils-643be57eb09fe6485ccc8f4cf3ac9a592c207bb5.tar.gz mailutils-643be57eb09fe6485ccc8f4cf3ac9a592c207bb5.tar.bz2 |
* comsat/Makefile.am: Remove cfg.c
* comsat/cfg.c: Remove.
* comsat/comsat.c: Use MU configuration and acls.
* comsat/comsat.h: Include acl.h
* libproto/maildir/mbox.c (maildir_qfetch): Bugfix.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | comsat/Makefile.am | 2 | ||||
-rw-r--r-- | comsat/cfg.c | 303 | ||||
-rw-r--r-- | comsat/comsat.c | 120 | ||||
-rw-r--r-- | comsat/comsat.h | 3 | ||||
-rw-r--r-- | libproto/maildir/mbox.c | 2 |
6 files changed, 100 insertions, 336 deletions
@@ -1,5 +1,11 @@ 2007-12-30 Sergey Poznyakoff <gray@gnu.org.ua> + * comsat/Makefile.am: Remove cfg.c + * comsat/cfg.c: Remove. + * comsat/comsat.c: Use MU configuration and acls. + * comsat/comsat.h: Include acl.h + * libproto/maildir/mbox.c (maildir_qfetch): Bugfix. + * NEWS: Update. * frm/testsuite/frm/test.exp: Call mu_init with -noflags option. diff --git a/comsat/Makefile.am b/comsat/Makefile.am index d60660fe3..0f861a8ed 100644 --- a/comsat/Makefile.am +++ b/comsat/Makefile.am @@ -21,7 +21,7 @@ INCLUDES = @MU_COMMON_INCLUDES@ sbin_PROGRAMS = comsatd -comsatd_SOURCES = action.c cfg.c comsat.c comsat.h +comsatd_SOURCES = action.c comsat.c comsat.h comsatd_LDADD = \ ${MU_APP_LIBRARIES}\ diff --git a/comsat/cfg.c b/comsat/cfg.c deleted file mode 100644 index 2f4f38170..000000000 --- a/comsat/cfg.c +++ /dev/null @@ -1,303 +0,0 @@ -/* This file is part of GNU Mailutils. - Copyright (C) 1998, 2001, 2002, 2005, 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. - - GNU Mailutils is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR 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 GNU Mailutils; see the file COPYING. If not, write - to the Free Software Foundation, Inc., 51 Franklin Street, - Fifth Floor, Boston, MA 02110-1301 USA. */ - -#include "comsat.h" - -typedef struct netdef netdef_t; - -struct netdef -{ - netdef_t *next; - unsigned int ipaddr; - unsigned int netmask; -}; - -#define ACT_ALLOW 0 -#define ACT_DENY 1 - -typedef struct acl acl_t; - -struct acl -{ - acl_t *next; - netdef_t *netlist; - int action; -}; - - -acl_t *acl_head, *acl_tail; - -#define DOTTED_QUAD_LEN 16 - -static int -read_address (char **line_ptr, char *ptr) -{ - char *startp = *line_ptr; - char *endp; - int dotcount = 0; - - for (endp = startp; *endp; endp++, ptr++) - if (!(isdigit (*endp) || *endp == '.')) - break; - else if (endp < startp + DOTTED_QUAD_LEN) - { - if (*endp == '.') - dotcount++; - *ptr = *endp; - } - else - break; - *line_ptr = endp; - *ptr = 0; - return dotcount; -} - -static netdef_t * -netdef_parse (char *str) -{ - unsigned int ipaddr, netmask; - netdef_t *netdef; - char ipbuf[DOTTED_QUAD_LEN+1]; - - if (strcmp (str, "any") == 0) - { - ipaddr = 0; - netmask = 0; - } - else - { - read_address (&str, ipbuf); - ipaddr = inet_addr (ipbuf); - if (ipaddr == INADDR_NONE) - return NULL; - if (*str == 0) - netmask = 0xfffffffful; - else if (*str != '/') - return NULL; - else - { - str++; - if (read_address (&str, ipbuf) == 0) - { - /* netmask length */ - unsigned int len = strtoul (ipbuf, NULL, 0); - if (len > 32) - return NULL; - netmask = 0xfffffffful >> (32-len); - netmask <<= (32-len); - } - else - netmask = inet_network (ipbuf); - netmask = htonl (netmask); - } - } - - netdef = malloc (sizeof *netdef); - if (!netdef) - { - mu_error (_("Out of memory")); - exit (1); - } - - netdef->next = NULL; - netdef->ipaddr = ipaddr; - netdef->netmask = netmask; - - return netdef; -} - -void -read_config (const char *config_file) -{ - FILE *fp; - int line; - char buf[128]; - char *ptr; - - if (!config_file) - return; - - fp = fopen (config_file, "r"); - if (!fp) - { - mu_error (_("Cannot open config file %s: %s"), config_file, - mu_strerror (errno)); - return; - } - - line = 0; - while ((ptr = fgets (buf, sizeof buf, fp))) - { - int len, i; - int argc; - char **argv; - int action; - netdef_t *head, *tail; - acl_t *acl; - - line++; - len = strlen (ptr); - if (len > 0 && ptr[len-1] == '\n') - ptr[--len] = 0; - - while (*ptr && isspace (*ptr)) - ptr++; - if (!*ptr || *ptr == '#') - continue; - - mu_argcv_get (ptr, "", NULL, &argc, &argv); - if (argc < 2) - { - mu_error (_("%s:%d: too few fields"), config_file, line); - mu_argcv_free (argc, argv); - continue; - } - - if (strcmp (argv[0], "allow-biffrc") == 0) - { - if (strcmp (argv[1], "yes") == 0) - allow_biffrc = 1; - else if (strcmp (argv[1], "no") == 0) - allow_biffrc = 0; - else - mu_error (_("%s:%d: yes or no expected"), config_file, line); - } - else if (strcmp (argv[0], "max-requests") == 0) - maxrequests = strtoul (argv[1], NULL, 0); - else if (strcmp (argv[0], "request-control-interval") == 0) - request_control_interval = strtoul (argv[1], NULL, 0); - else if (strcmp (argv[0], "overflow-control-interval") == 0) - overflow_control_interval = strtoul (argv[1], NULL, 0); - else if (strcmp (argv[0], "overflow-delay-time") == 0) - overflow_delay_time = strtoul (argv[1], NULL, 0); - else if (strcmp (argv[0], "max-lines") == 0) - maxlines = strtoul (argv[1], NULL, 0); - else if (strcmp (argv[0], "acl") == 0) - { - if (strcmp (argv[1], "allow") == 0) - action = ACT_ALLOW; - else if (strcmp (argv[1], "deny") == 0) - action = ACT_DENY; - else - { - mu_error (_("%s:%d: unknown keyword"), config_file, line); - mu_argcv_free (argc, argv); - continue; - } - - head = tail = NULL; - for (i = 2; i < argc; i++) - { - netdef_t *cur = netdef_parse (argv[i]); - if (!cur) - { - mu_error (_("%s:%d: cannot parse netdef: %s"), - config_file, line, argv[i]); - continue; - } - if (!tail) - head = cur; - else - tail->next = cur; - tail = cur; - } - - mu_argcv_free (argc, argv); - - acl = malloc (sizeof *acl); - if (!acl) - { - mu_error (_("Out of memory")); - exit (1); - } - acl->next = NULL; - acl->action = action; - acl->netlist = head; - - if (!acl_tail) - acl_head = acl; - else - acl_tail->next = acl; - acl_tail = acl; - } - } - fclose (fp); -} - -/*NOTE: currently unused. */ -#if 0 -static void -netdef_free (netdef_t *netdef) -{ - netdef_t *next; - - while (netdef) - { - next = netdef->next; - free (netdef); - netdef = next; - } -} - -static void -acl_free (acl_t *acl) -{ - acl_t *next; - - while (acl) - { - next = acl->next; - netdef_free (acl->netlist); - free (acl); - acl = next; - } -} - -static void -discard_acl (acl_t *mark) -{ - if (mark) - { - acl_free (mark->next); - acl_tail = mark; - acl_tail->next = NULL; - } - else - acl_head = acl_tail = NULL; -} -#endif - -int -acl_match (struct sockaddr_in *sa_in) -{ - acl_t *acl; - unsigned int ip; - - ip = sa_in->sin_addr.s_addr; - for (acl = acl_head; acl; acl = acl->next) - { - netdef_t *net; - - for (net = acl->netlist; net; net = net->next) - { - if (net->ipaddr == (ip & net->netmask)) - return acl->action; - } - } - return ACT_ALLOW; -} diff --git a/comsat/comsat.c b/comsat/comsat.c index 099866302..3c81d6f71 100644 --- a/comsat/comsat.c +++ b/comsat/comsat.c @@ -103,6 +103,7 @@ struct mu_gocs_daemon default_gocs_daemon = { int maxlines = 5; char hostname[MAXHOSTNAMELEN]; const char *username; +mu_acl_t comsat_acl; static void comsat_init (void); static void comsat_daemon_init (void); @@ -116,7 +117,6 @@ static void change_user (const char *user); static int xargc; static char **xargv; -char *config_file = NULL; int test_mode; static error_t @@ -125,7 +125,7 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) switch (key) { case 'c': - config_file = arg; + /* FIXME: convert config to the new format and parse it */ break; case 't': @@ -138,20 +138,43 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) return 0; } +struct mu_cfg_param comsat_cfg_param[] = { + { "allow-biffrc", mu_cfg_bool, &allow_biffrc, 0, NULL, + N_("Read .biffrc file from the user home directory") }, + { "max-lines", mu_cfg_int, &maxlines, 0, NULL, + N_("Maximum number of message body lines to be output.") }, + { "max-requests", mu_cfg_uint, &maxrequests, 0, NULL, + N_("Maximum number of incoming requests per `request-control-interval' " + "seconds.") }, + { "request-control-interval", mu_cfg_time, &request_control_interval, + 0, NULL, + N_("Set control interval.") }, + { "overflow-control-interval", mu_cfg_time, &overflow_control_interval, + 0, NULL, + N_("Set overflow control interval.") }, + { "overflow-delay-time", mu_cfg_time, &overflow_delay_time, + 0, NULL, + N_("Time to sleep after the first overflow occurs.") }, + { "acl", mu_cfg_section, }, + { NULL } +}; int main (int argc, char **argv) { int c; int ind; - + /* Native Language Support */ mu_init_nls (); mu_argp_init (program_version, NULL); mu_gocs_daemon = default_gocs_daemon; + comsat_init (); + mu_acl_cfg_init (); - if (mu_app_init (&argp, comsat_argp_capa, NULL, argc, argv, 0, &ind, NULL)) + if (mu_app_init (&argp, comsat_argp_capa, comsat_cfg_param, argc, argv, 0, + &ind, &comsat_acl)) exit (1); argc -= ind; @@ -161,11 +184,6 @@ main (int argc, char **argv) { char *user; - comsat_init (); - if (config_file) - read_config (config_file); - if (argc == 0) - exit (0); if (argc < 2 || argc > 2) { mu_error (_("Mailbox URL and message QID are required in test mode")); @@ -198,8 +216,6 @@ main (int argc, char **argv) exit (EXIT_FAILURE); } - comsat_init (); - if (mu_gocs_daemon.mode == MODE_DAEMON) { /* Preserve invocation arguments */ @@ -218,9 +234,6 @@ main (int argc, char **argv) mu_debug_set_print (debug, mu_diag_syslog_printer, NULL); } - if (config_file) - read_config (config_file); - chdir ("/"); if (mu_gocs_daemon.mode == MODE_DAEMON) @@ -370,11 +383,58 @@ comsat_daemon (int port) } int +check_connection (int fd, struct sockaddr *addr, socklen_t addrlen) +{ + switch (addr->sa_family) + { + case PF_UNIX: + mu_diag_output (MU_DIAG_INFO, _("connect from socket")); + break; + + case PF_INET: + { + struct sockaddr_in *s_in = (struct sockaddr_in *)addr; + + if (comsat_acl) + { + mu_acl_result_t res; + + int rc = mu_acl_check_sockaddr (comsat_acl, addr, addrlen, + &res); + if (rc) + { + mu_error (_("Access from %s blocked: cannot check ACLs: %s"), + inet_ntoa (s_in->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 (s_in->sin_addr)); + break; + + case mu_acl_result_accept: + break; + + case mu_acl_result_deny: + mu_error (_("Access from %s blocked."), + inet_ntoa (s_in->sin_addr)); + return 1; + } + } + } + } + return 0; +} + +int comsat_main (int fd) { int rdlen; int len; - struct sockaddr_in sin_from; + struct sockaddr fromaddr; char buffer[216]; /*FIXME: Arbitrary size */ pid_t pid; char tty[MAX_TTY_SIZE]; @@ -382,9 +442,8 @@ comsat_main (int fd) char *path = NULL; mu_message_qid_t qid; - len = sizeof sin_from; - rdlen = recvfrom (fd, buffer, sizeof buffer, 0, - (struct sockaddr*)&sin_from, &len); + len = sizeof fromaddr; + rdlen = recvfrom (fd, buffer, sizeof buffer, 0, &fromaddr, &len); if (rdlen <= 0) { if (errno == EINTR) @@ -393,19 +452,16 @@ comsat_main (int fd) return 1; } - if (acl_match (&sin_from)) - { - mu_diag_output (MU_DIAG_ALERT, _("DENIED attempt to connect from %s"), - inet_ntoa (sin_from.sin_addr)); - return 1; - } + if (check_connection (fd, &fromaddr, len)) + return 1; mu_diag_output (MU_DIAG_INFO, - ngettext ("Received %d byte from %s", - "Received %d bytes from %s", rdlen), - rdlen, inet_ntoa (sin_from.sin_addr)); - + ngettext ("Received %d byte from %s", + "Received %d bytes from %s", rdlen), + rdlen, inet_ntoa (((struct sockaddr_in*)&fromaddr)->sin_addr)); + buffer[rdlen] = 0; + mu_diag_output (MU_DIAG_INFO, "string: %s", buffer); /* Parse the buffer */ p = strchr (buffer, '@'); @@ -417,7 +473,13 @@ comsat_main (int fd) *p++ = 0; qid = p; - + p = strchr (qid, ':'); + if (p) + { + *p++ = 0; + path = p; + } + if (find_user (buffer, tty) != SUCCESS) return 0; diff --git a/comsat/comsat.h b/comsat/comsat.h index 62fefa871..ec6fd6016 100644 --- a/comsat/comsat.h +++ b/comsat/comsat.h @@ -60,6 +60,7 @@ #include <mailutils/argcv.h> #include <mailutils/nls.h> #include <mailutils/daemon.h> +#include <mailutils/acl.h> #ifndef INADDR_NONE # define INADDR_NONE -1 @@ -77,6 +78,4 @@ extern const char *username; extern char hostname[]; extern struct daemon_param daemon_param; -extern void read_config (const char *config_file); -int acl_match (struct sockaddr_in *sa_in); void run_user_action (FILE *tty, const char *cr, mu_message_t msg); diff --git a/libproto/maildir/mbox.c b/libproto/maildir/mbox.c index d9e062755..635215190 100644 --- a/libproto/maildir/mbox.c +++ b/libproto/maildir/mbox.c @@ -669,7 +669,7 @@ maildir_qfetch (struct _amd_data *amd, mu_message_qid_t qid) if (!name) return EINVAL; - + name++; msg = calloc (1, sizeof(*msg)); msg->file_name = strdup (name); |