diff options
53 files changed, 2416 insertions, 980 deletions
diff --git a/am/ipv6.m4 b/am/ipv6.m4 new file mode 100644 index 000000000..2357314b9 --- /dev/null +++ b/am/ipv6.m4 @@ -0,0 +1,56 @@ +dnl This file is part of GNU Mailutils. -*- autoconf -*- +dnl Copyright (C) 2011 Free Software Foundation, Inc. +dnl +dnl GNU Mailutils is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl GNU Mailutils is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. + +AC_DEFUN([MU_ENABLE_IPV6], + [AC_ARG_ENABLE(ipv6, + [AC_HELP_STRING([--enable-ipv6], [enable IPv6 support])], + [status_ipv6=$enableval], + [status_ipv6=maybe]) + + if test $status_ipv6 != no; then + working_ipv6=no + AC_EGREP_CPP(MAILUTILS_AF_INET6_DEFINED,[ +#include <sys/socket.h> +#if defined(AF_INET6) +MAILUTILS_AF_INET6_DEFINED +#endif +],[working_ipv6=yes]) + + AC_CHECK_TYPE([struct sockaddr_storage], + [working_ipv6=yes], [working_ipv6=no], + [#include <sys/socket.h>]) + AC_CHECK_TYPE([struct sockaddr_in6], + [working_ipv6=yes], [working_ipv6=no], + [#include <sys/types.h> + #include <netinet/in.h>]) + AC_CHECK_TYPE([struct addrinfo], + [working_ipv6=yes], [working_ipv6=no], + [#include <netdb.h>]) + AC_CHECK_FUNC([getnameinfo], + [working_ipv6=yes], [working_ipv6=no], + [#include <netdb.h>]) + + if test $working_ipv6 = no; then + if test $status_ipv6 = yes; then + AC_MSG_ERROR([IPv6 support is required but not available]) + fi + fi + status_ipv6=$working_ipv6 + if test $status_ipv6 = yes; then + AC_DEFINE_UNQUOTED([MAILUTILS_IPV6],1, + [Define to 1 if IPv6 support is enabled]) + fi + fi])
\ No newline at end of file diff --git a/configure.ac b/configure.ac index e03a4c3b3..2edb49459 100644 --- a/configure.ac +++ b/configure.ac @@ -541,6 +541,10 @@ AH_BOTTOM([ ]) +# IPv6 support +MU_ENABLE_IPV6 + + ## FriBidi support AC_CHECK_FUNCS(wcwidth) @@ -1285,6 +1289,8 @@ LDAP support .................. $status_ldap Radius support ................ $status_radius Support for virtual domains ... $status_virtual_domains +IPv6 support .................. $status_ipv6 + Interfaces: Guile ......................... $status_guile @@ -1332,6 +1338,7 @@ status_mh=$mu_cv_enable_mh status_maildir=$mu_cv_enable_maildir status_smtp=$mu_cv_enable_smtp status_sendmail=$mu_cv_enable_sendmail +status_ipv6=$status_ipv6 ]) dnl Output Makefiles @@ -1382,6 +1389,8 @@ AC_CONFIG_FILES([ libmailutils/auth/Makefile libmailutils/base/Makefile libmailutils/address/Makefile + libmailutils/sockaddr/Makefile + libmailutils/cidr/Makefile libmailutils/cfg/Makefile libmailutils/diag/Makefile libmailutils/filter/Makefile diff --git a/examples/.gitignore b/examples/.gitignore index af4156be3..890812aae 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -11,6 +11,7 @@ iconv listop lsf mailcap +mblconv mimetest msg-send mta @@ -20,5 +21,6 @@ muemail murun musocio nntpclient +sa sfrom url-parse diff --git a/examples/Makefile.am b/examples/Makefile.am index e22a8d355..9df91ea62 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -43,6 +43,7 @@ noinst_PROGRAMS = \ murun\ musocio\ $(NNTPCLIENT)\ + sa\ sfrom EXTRA_PROGRAMS = nntpclient diff --git a/examples/aclck.c b/examples/aclck.c index 57f5c0388..033c444b1 100644 --- a/examples/aclck.c +++ b/examples/aclck.c @@ -28,35 +28,9 @@ #include <stdlib.h> #include <string.h> -struct sockaddr *target_sa; -int target_salen; +struct mu_sockaddr *target_sa; mu_acl_t acl; -struct sockaddr * -parse_address (int *psalen, char *str) -{ - struct sockaddr_in in; - struct sockaddr *sa; - - in.sin_family = AF_INET; - if (inet_aton (str, &in.sin_addr) == 0) - { - mu_error ("Invalid IPv4: %s", str); - exit (1); - } - in.sin_port = 0; - *psalen = sizeof (in); - sa = malloc (*psalen); - if (!sa) - { - mu_error ("%s", mu_strerror (errno)); - exit (1); - } - - memcpy (sa, &in, sizeof (in)); - return sa; -} - void read_rules (FILE *fp) { @@ -76,12 +50,9 @@ read_rules (FILE *fp) ws.ws_comment = "#"; while (fgets (buf, sizeof buf, fp)) { - unsigned long netmask; - int salen; - struct sockaddr *sa; + struct mu_cidr cidr; mu_acl_action_t action; void *data = NULL; - char *p; int len = strlen (buf); if (len == 0) @@ -109,47 +80,19 @@ read_rules (FILE *fp) continue; } - p = strchr (ws.ws_wordv[1], '/'); - if (p) + if (strcmp (ws.ws_wordv[1], "any") == 0) + memset (&cidr, 0, sizeof (cidr)); + else { - 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 == '.') + rc = mu_cidr_from_string (&cidr, ws.ws_wordv[1]); + if (rc) { - struct in_addr addr; - - if (inet_aton (p, &addr) == 0) - { - mu_error ("%d: invalid netmask", line); - continue; - } - netmask = addr.s_addr; - } - else - { - mu_error ("%d: invalid netmask", line); + mu_error ("%d: invalid source CIDR: %s", + line, mu_strerror (rc)); continue; } } - else - netmask = 0xfffffffful; - - sa = parse_address (&salen, ws.ws_wordv[1]); - + /* accept addr deny addr log addr [rest ...] @@ -174,7 +117,7 @@ read_rules (FILE *fp) data = strdup (ws.ws_wordv[2]); } - rc = mu_acl_append (acl, action, data, sa, salen, netmask); + rc = mu_acl_append (acl, action, data, &cidr); if (rc) mu_error ("%d: cannot append acl entry: %s", line, mu_strerror (rc)); @@ -203,7 +146,12 @@ main (int argc, char **argv) break; case 'a': - target_sa = parse_address (&target_salen, optarg); + rc = mu_sockaddr_from_node (&target_sa, optarg, NULL, NULL); + if (rc) + { + mu_error ("mu_sockaddr_from_node: %s", mu_strerror (rc)); + exit (1); + } break; case 'f': @@ -225,7 +173,8 @@ main (int argc, char **argv) argc -= optind; read_rules (file ? file : stdin); - rc = mu_acl_check_sockaddr (acl, target_sa, target_salen, &result); + rc = mu_acl_check_sockaddr (acl, target_sa->addr, target_sa->addrlen, + &result); if (rc) { mu_error ("mu_acl_check_sockaddr failed: %s", mu_strerror (rc)); diff --git a/examples/echosrv.c b/examples/echosrv.c index fb68e7aee..fffde7343 100644 --- a/examples/echosrv.c +++ b/examples/echosrv.c @@ -39,13 +39,9 @@ echo_conn (int fd, struct sockaddr *s, int len, void *server_data, void *call_data, mu_ip_server_t srv) { - struct sockaddr_in srv_addr, *s_in = (struct sockaddr_in *)s; - int addrlen = sizeof srv_addr; pid_t pid; char buf[512]; FILE *in, *out; - - mu_ip_server_get_sockaddr (srv, (struct sockaddr *)&srv_addr, &addrlen); pid = fork (); if (pid == -1) @@ -56,10 +52,20 @@ echo_conn (int fd, struct sockaddr *s, int len, if (pid) { - mu_diag_output (MU_DIAG_INFO, "%lu: opened connection %s:%d => %s:%d", + struct mu_sockaddr *clt_addr; + int rc = mu_sockaddr_create (&clt_addr, s, len); + if (rc) + { + mu_error ("mu_sockaddr_create failed: %s", mu_strerror (rc)); + return 0; + } + + mu_diag_output (MU_DIAG_INFO, "%lu: opened connection %s => %s", (unsigned long) pid, - inet_ntoa (srv_addr.sin_addr), ntohs (srv_addr.sin_port), - inet_ntoa (s_in->sin_addr), ntohs (s_in->sin_port)); + mu_ip_server_addrstr (srv), + mu_sockaddr_str (clt_addr)); + + mu_sockaddr_free (clt_addr); return 0; } @@ -108,34 +114,45 @@ tcp_conn_free (void *conn_data, void *server_data) void create_server (char *arg) { - char *p, *q; - struct sockaddr_in s; + struct mu_sockaddr *s; mu_ip_server_t tcpsrv; - unsigned n; - - p = strchr (arg, ':'); - if (!*p) + int rc; + mu_url_t url, url_hint; + struct mu_sockaddr_hints hints; + + if (arg[0] == '/') + url_hint = NULL; + else { - mu_error ("invalid specification: %s\n", arg); - exit (1); + rc = mu_url_create (&url_hint, "inet://"); + if (rc) + { + mu_error ("cannot create URL hints: %s", mu_strerror (rc)); + exit (1); + } } - *p++ = 0; - s.sin_family = AF_INET; - if (inet_aton (arg, &s.sin_addr) == 0) + rc = mu_url_create_hint (&url, arg, MU_URL_PARSE_DEFAULT, url_hint); + mu_url_destroy (&url_hint); + if (rc) { - mu_error ("invalid IP address: %s\n", arg); + mu_error ("cannot parse URL `%s': %s", arg, mu_strerror (rc)); exit (1); } - n = strtoul (p, &q, 0); - if (*q) + + memset (&hints, sizeof(hints), 0); + hints.flags = MU_AH_PASSIVE; + hints.socktype = SOCK_STREAM; + hints.protocol = IPPROTO_TCP; + rc = mu_sockaddr_from_url (&s, url, &hints); + mu_url_destroy (&url); + + if (rc) { - mu_error ("invalid port number: %s\n", p); + mu_error ("cannot create sockaddr: %s", mu_strerror (rc)); exit (1); - } - s.sin_port = htons (n); + } - MU_ASSERT (mu_ip_server_create (&tcpsrv, (struct sockaddr*) &s, sizeof s, - MU_IP_TCP)); + MU_ASSERT (mu_ip_server_create (&tcpsrv, s, MU_IP_TCP)); MU_ASSERT (mu_ip_server_open (tcpsrv)); MU_ASSERT (mu_ip_server_set_conn (tcpsrv, echo_conn)); MU_ASSERT (mu_server_add_connection (server, diff --git a/examples/sa.c b/examples/sa.c new file mode 100644 index 000000000..7cc7e93b5 --- /dev/null +++ b/examples/sa.c @@ -0,0 +1,93 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2010, 2011 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 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <mailutils/mailutils.h> + +int +main (int argc, char **argv) +{ + struct mu_sockaddr_hints hints; + struct mu_sockaddr *sa, *ap; + int rc, i; + char *node = NULL, *serv = NULL; + char *urlstr; + + mu_set_program_name (argv[0]); + + memset (&hints, 0, sizeof (hints)); + hints.family = AF_UNSPEC; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "passive") == 0) + hints.flags |= MU_AH_PASSIVE; + else if (strcmp (argv[i], "detect") == 0) + hints.flags |= MU_AH_DETECT_FAMILY; + else if (strncmp (argv[i], "node=", 5) == 0) + node = argv[i] + 5; + else if (strncmp (argv[i], "serv=", 5) == 0) + serv = argv[i] + 5; + else if (strncmp (argv[i], "url=", 4) == 0) + urlstr = argv[i] + 4; + else if (strncmp (argv[i], "proto=", 6) == 0) + hints.protocol = atoi(argv[i] + 6); + else if (strncmp (argv[i], "family=", 7) == 0) + hints.family = atoi (argv[i] + 7); + else if (strncmp (argv[i], "socktype=", 9) == 0) + hints.socktype = atoi (argv[i] + 9); + else + { + mu_error ("unknown argument: %s", argv[i]); + exit (1); + } + } + + if (urlstr) + { + mu_url_t url; + + if (node || serv) + { + mu_error ("both url and host/serv are given"); + exit (1); + } + + rc = mu_url_create (&url, urlstr); + if (rc) + { + mu_error ("cannot create url: %s", mu_strerror (rc)); + exit (2); + } + rc = mu_sockaddr_from_url (&sa, url, &hints); + } + else + rc = mu_sockaddr_from_node (&sa, node, serv, &hints); + if (rc) + { + mu_error ("cannot create sockaddr: %s", mu_strerror (rc)); + exit (2); + } + + for (ap = sa; ap; ap = ap->next) + printf ("%s\n", mu_sockaddr_str (ap)); + + mu_sockaddr_free (sa); + exit (0); +} + diff --git a/include/mailutils/Makefile.am b/include/mailutils/Makefile.am index daa46e9fe..1e2189437 100644 --- a/include/mailutils/Makefile.am +++ b/include/mailutils/Makefile.am @@ -36,6 +36,7 @@ pkginclude_HEADERS = \ body.h\ cctype.h\ cfg.h\ + cidr.h\ cstr.h\ daemon.h\ debug.h\ @@ -89,6 +90,7 @@ pkginclude_HEADERS = \ server.h\ sieve.h\ smtp.h\ + sockaddr.h\ stdstream.h\ stream.h\ syslog.h\ diff --git a/include/mailutils/acl.h b/include/mailutils/acl.h index b898463eb..167acc82c 100644 --- a/include/mailutils/acl.h +++ b/include/mailutils/acl.h @@ -47,13 +47,11 @@ int mu_acl_destroy (mu_acl_t *acl); int mu_acl_count (mu_acl_t acl, size_t *pcount); int mu_acl_get_iterator (mu_acl_t acl, mu_iterator_t *pitr); int mu_acl_append (mu_acl_t acl, mu_acl_action_t act, void *data, - struct sockaddr *sa, int salen, - unsigned long netmask); + struct mu_cidr *); int mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, - struct sockaddr *sa, int salen, unsigned long netmask); + struct mu_cidr *); int mu_acl_insert (mu_acl_t acl, size_t pos, int before, - mu_acl_action_t act, void *data, - struct sockaddr *sa, int salen, unsigned long netmask); + mu_acl_action_t act, void *data, struct mu_cidr *); int mu_acl_check_ipv4 (mu_acl_t acl, unsigned int addr, mu_acl_result_t *pres); int mu_acl_check_inaddr (mu_acl_t acl, const struct in_addr *inp, diff --git a/include/mailutils/cidr.h b/include/mailutils/cidr.h new file mode 100644 index 000000000..c54bf6224 --- /dev/null +++ b/include/mailutils/cidr.h @@ -0,0 +1,61 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MAILUTILS_CIDR_H +#define _MAILUTILS_CIDR_H + +#include <sys/types.h> +#include <sys/socket.h> +#include <mailutils/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define MU_INADDR_BYTES 16 + +struct mu_cidr +{ + int family; + int len; + unsigned char address[MU_INADDR_BYTES]; + unsigned char netmask[MU_INADDR_BYTES]; +}; + +#define MU_CIDR_MAXBUFSIZE 81 + +int mu_cidr_from_sockaddr (struct mu_cidr *cp, const struct sockaddr *sa); +int mu_cidr_from_string (struct mu_cidr *cp, const char *str); + +#define MU_CIDR_FMT_ADDRONLY 0x01 + +int mu_cidr_to_string (struct mu_cidr *cidr, int flags, char *buf, size_t size, + size_t *pret); +int mu_cidr_format (struct mu_cidr *, int flags, char **pbuf); +int mu_cidr_to_sockaddr (struct mu_cidr *, struct sockaddr **sa); + +int mu_cidr_match (struct mu_cidr *a, struct mu_cidr *b); + +int _mu_inaddr_to_bytes (int af, void *buf, unsigned char *bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* _MAILUTILS_CIDR_H */ + + diff --git a/include/mailutils/debug.h b/include/mailutils/debug.h index 5072d51d2..a619661d7 100644 --- a/include/mailutils/debug.h +++ b/include/mailutils/debug.h @@ -54,9 +54,6 @@ extern int mu_debug_line_info; struct sockaddr; -void mu_sockaddr_to_str (const struct sockaddr *sa, int salen, - char *bufptr, size_t buflen, - size_t *plen); char *mu_sockaddr_to_astr (const struct sockaddr *sa, int salen); diff --git a/include/mailutils/mailutils.h b/include/mailutils/mailutils.h index 8d9e04b77..08a2fc0bc 100644 --- a/include/mailutils/mailutils.h +++ b/include/mailutils/mailutils.h @@ -67,5 +67,7 @@ #include <mailutils/log.h> #include <mailutils/stdstream.h> #include <mailutils/prog.h> +#include <mailutils/sockaddr.h> +#include <mailutils/cidr.h> /* EOF */ diff --git a/include/mailutils/server.h b/include/mailutils/server.h index bf8d10e6f..c5da97e43 100644 --- a/include/mailutils/server.h +++ b/include/mailutils/server.h @@ -54,8 +54,8 @@ typedef void (*mu_ip_server_free_fp) (void *data); #define MU_IP_TCP 0 #define MU_IP_UDP 1 -int mu_ip_server_create (mu_ip_server_t *psrv, struct sockaddr *addr, - int len, int type); +int mu_ip_server_create (mu_ip_server_t *psrv, struct mu_sockaddr *addr, + int type); int mu_ip_server_destroy (mu_ip_server_t *psrv); int mu_ip_server_get_type (mu_ip_server_t srv, int *ptype); int mu_ip_server_set_ident (mu_ip_server_t srv, const char *ident); @@ -69,8 +69,8 @@ int mu_ip_server_shutdown (mu_ip_server_t srv); int mu_ip_server_accept (mu_ip_server_t srv, void *call_data); int mu_ip_server_loop (mu_ip_server_t srv, void *call_data); int mu_ip_server_get_fd (mu_ip_server_t srv); -int mu_ip_server_get_sockaddr (mu_ip_server_t srv, struct sockaddr *s, - int *size); +int mu_ip_server_get_sockaddr (mu_ip_server_t srv, struct mu_sockaddr **psa); +const char *mu_ip_server_addrstr (mu_ip_server_t srv); int mu_tcp_server_set_backlog (mu_ip_server_t srv, int backlog); int mu_udp_server_set_bufsize (mu_ip_server_t srv, size_t size); @@ -99,8 +99,6 @@ void mu_m_server_set_max_children (mu_m_server_t srv, size_t num); int mu_m_server_set_pidfile (mu_m_server_t srv, const char *pidfile); int mu_m_server_set_foreground (mu_m_server_t srv, int enable); void mu_m_server_set_default_port (mu_m_server_t srv, int port); -void mu_m_server_set_default_address (mu_m_server_t srv, struct sockaddr *sa, - int salen); void mu_m_server_set_timeout (mu_m_server_t srv, time_t t); void mu_m_server_set_mode (mu_m_server_t srv, int mode); void mu_m_server_set_sigset (mu_m_server_t srv, sigset_t *sigset); @@ -112,8 +110,6 @@ time_t mu_m_server_timeout (mu_m_server_t srv); const char * mu_m_server_pidfile (mu_m_server_t srv); void mu_m_server_get_sigset (mu_m_server_t srv, sigset_t *sigset); int mu_m_server_get_srvlist (mu_m_server_t srv, mu_list_t *plist); -int mu_m_server_get_default_address (mu_m_server_t srv, struct sockaddr *sa, - int *salen); void mu_m_server_configured_count (mu_m_server_t msrv, size_t count); diff --git a/include/mailutils/s |