Re: syslogd ipv6 proto6

2014-08-25 Thread Alexander Bluhm
On Sat, Aug 23, 2014 at 01:10:52PM +0200, Alexander Bluhm wrote:
 On Fri, Aug 22, 2014 at 06:43:47PM +0200, Alexander Bluhm wrote:
  At the moment syslogd opens both IPv4 and IPv6 sockets unconditionally.
  I can restrict it to a protocol family with -4 and -6 command line
  switches.  If the log server is a FQDN, DNS chosses wether to take
  the IPv4 or IPv6 route.  For that I have invented a udp4:// or
  udp6:// prefix to choose a protocol.  This syntax was chosen as I
  want to extend it to tcp:// and tls:// later.
 
 Before -46 and -64 disabled both protocols.  halex@ suggested to
 use the latter one like other programs do.
 
 updated diff changed in the getopt switch, ok?

I still need an ok for this.  The -4 switch has been made especially
for our ipv6 haters^W^Wipv4 lovers.  I can live without it.

When implementing tcp, I will need the tcp:// logic anyway.

bluhm

 
 Index: usr.sbin/syslogd/privsep.c
 ===
 RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
 retrieving revision 1.40
 diff -u -p -r1.40 privsep.c
 --- usr.sbin/syslogd/privsep.c21 Aug 2014 17:00:34 -  1.40
 +++ usr.sbin/syslogd/privsep.c23 Aug 2014 11:01:38 -
 @@ -101,8 +101,8 @@ int
  priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
  {
   int i, fd, socks[2], cmd, addr_len, result, restart;
 - size_t path_len, hostname_len, servname_len;
 - char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN];
 + size_t path_len, protoname_len, hostname_len, servname_len;
 + char path[MAXPATHLEN], protoname[5], hostname[MAXHOSTNAMELEN];
   char servname[NI_MAXSERV];
   struct sockaddr_storage addr;
   struct stat cf_stat;
 @@ -293,7 +293,14 @@ priv_init(char *conf, int numeric, int l
  
   case PRIV_GETADDRINFO:
   dprintf([priv]: msg PRIV_GETADDRINFO received\n);
 - /* Expecting: len, hostname, len, servname */
 + /* Expecting: len, proto, len, host, len, serv */
 + must_read(socks[0], protoname_len, sizeof(size_t));
 + if (protoname_len == 0 ||
 + protoname_len  sizeof(protoname))
 + _exit(1);
 + must_read(socks[0], protoname, protoname_len);
 + protoname[protoname_len - 1] = '\0';
 +
   must_read(socks[0], hostname_len, sizeof(size_t));
   if (hostname_len == 0 ||
   hostname_len  sizeof(hostname))
 @@ -309,8 +316,17 @@ priv_init(char *conf, int numeric, int l
   servname[servname_len - 1] = '\0';
  
   memset(hints, 0, sizeof(hints));
 - hints.ai_family = AF_UNSPEC;
 + if (strcmp(protoname, udp) == 0) {
 + hints.ai_family = AF_UNSPEC;
 + } else if (strcmp(protoname, udp4) == 0) {
 + hints.ai_family = AF_INET;
 + } else if (strcmp(protoname, udp6) == 0) {
 + hints.ai_family = AF_INET6;
 + } else {
 + errx(1, unknown protocol %s, protoname);
 + }
   hints.ai_socktype = SOCK_DGRAM;
 + hints.ai_protocol = IPPROTO_UDP;
   i = getaddrinfo(hostname, servname, hints, res0);
   if (i != 0 || res0 == NULL) {
   addr_len = 0;
 @@ -661,25 +677,30 @@ priv_config_parse_done(void)
  /* Name/service to address translation.  Response is placed into addr.
   * Return 0 for success or  0 for error like getaddrinfo(3) */
  int
 -priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
 +priv_getaddrinfo(char *proto, char *host, char *serv, struct sockaddr *addr,
  size_t addr_len)
  {
 - char hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
 + char protocpy[5], hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
   int cmd, ret_len;
 - size_t hostname_len, servname_len;
 + size_t protoname_len, hostname_len, servname_len;
  
   if (priv_fd  0)
   errx(1, %s: called from privileged portion, __func__);
  
 - if (strlcpy(hostcpy, host, sizeof hostcpy) = sizeof(hostcpy))
 + if (strlcpy(protocpy, proto, sizeof(protocpy)) = sizeof(protocpy))
 + errx(1, %s: overflow attempt in protoname, __func__);
 + protoname_len = strlen(protocpy) + 1;
 + if (strlcpy(hostcpy, host, sizeof(hostcpy)) = sizeof(hostcpy))
   errx(1, %s: overflow attempt in hostname, __func__);
   hostname_len = strlen(hostcpy) + 1;
 - if (strlcpy(servcpy, serv, sizeof servcpy) = sizeof(servcpy))
 + if (strlcpy(servcpy, serv, sizeof(servcpy)) = sizeof(servcpy))
   errx(1, %s: overflow attempt in servname, __func__);

Re: syslogd ipv6 proto6

2014-08-25 Thread Alexander Bluhm
On Fri, Aug 22, 2014 at 06:43:47PM +0200, Alexander Bluhm wrote:
 At the moment syslogd opens both IPv4 and IPv6 sockets unconditionally.
 I can restrict it to a protocol family with -4 and -6 command line
 switches.  If the log server is a FQDN, DNS chosses wether to take
 the IPv4 or IPv6 route.  For that I have invented a udp4:// or
 udp6:// prefix to choose a protocol.  This syntax was chosen as I
 want to extend it to tcp:// and tls:// later.

And here is the documentation.

ok?

bluhm

Index: usr.sbin/syslogd/syslog.conf.5
===
RCS file: /cvs/src/usr.sbin/syslogd/syslog.conf.5,v
retrieving revision 1.25
diff -u -p -r1.25 syslog.conf.5
--- usr.sbin/syslogd/syslog.conf.5  21 Aug 2014 17:16:37 -  1.25
+++ usr.sbin/syslogd/syslog.conf.5  25 Aug 2014 19:22:09 -
@@ -227,6 +227,8 @@ square brackets
 and
 .Ql ]\
 .Pc .
+A prefix udp4:// or udp6:// in front of the hostname and after the
+at sign will force IPv4 or IPv6 addresses for UDP transport.
 .It
 A comma separated list of users.
 Selected messages are written to those users
Index: usr.sbin/syslogd/syslogd.8
===
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.8,v
retrieving revision 1.29
diff -u -p -r1.29 syslogd.8
--- usr.sbin/syslogd/syslogd.8  23 Jul 2014 05:57:36 -  1.29
+++ usr.sbin/syslogd/syslogd.8  25 Aug 2014 19:22:09 -
@@ -39,7 +39,7 @@
 .Sh SYNOPSIS
 .Nm syslogd
 .Bk -words
-.Op Fl dhnu
+.Op Fl 46dhnu
 .Op Fl a Ar path
 .Op Fl f Ar config_file
 .Op Fl m Ar mark_interval
@@ -54,6 +54,14 @@ configuration file.
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl 4
+Forces
+.Nm
+to use IPv4 addresses only.
+.It Fl 6
+Forces
+.Nm
+to use IPv6 addresses only.
 .It Fl a Ar path
 Specify a location where
 .Nm



Re: syslogd ipv6 proto6

2014-08-23 Thread Alexander Bluhm
On Fri, Aug 22, 2014 at 06:43:47PM +0200, Alexander Bluhm wrote:
 At the moment syslogd opens both IPv4 and IPv6 sockets unconditionally.
 I can restrict it to a protocol family with -4 and -6 command line
 switches.  If the log server is a FQDN, DNS chosses wether to take
 the IPv4 or IPv6 route.  For that I have invented a udp4:// or
 udp6:// prefix to choose a protocol.  This syntax was chosen as I
 want to extend it to tcp:// and tls:// later.

Before -46 and -64 disabled both protocols.  halex@ suggested to
use the latter one like other programs do.

updated diff changed in the getopt switch, ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.40
diff -u -p -r1.40 privsep.c
--- usr.sbin/syslogd/privsep.c  21 Aug 2014 17:00:34 -  1.40
+++ usr.sbin/syslogd/privsep.c  23 Aug 2014 11:01:38 -
@@ -101,8 +101,8 @@ int
 priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
 {
int i, fd, socks[2], cmd, addr_len, result, restart;
-   size_t path_len, hostname_len, servname_len;
-   char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN];
+   size_t path_len, protoname_len, hostname_len, servname_len;
+   char path[MAXPATHLEN], protoname[5], hostname[MAXHOSTNAMELEN];
char servname[NI_MAXSERV];
struct sockaddr_storage addr;
struct stat cf_stat;
@@ -293,7 +293,14 @@ priv_init(char *conf, int numeric, int l
 
case PRIV_GETADDRINFO:
dprintf([priv]: msg PRIV_GETADDRINFO received\n);
-   /* Expecting: len, hostname, len, servname */
+   /* Expecting: len, proto, len, host, len, serv */
+   must_read(socks[0], protoname_len, sizeof(size_t));
+   if (protoname_len == 0 ||
+   protoname_len  sizeof(protoname))
+   _exit(1);
+   must_read(socks[0], protoname, protoname_len);
+   protoname[protoname_len - 1] = '\0';
+
must_read(socks[0], hostname_len, sizeof(size_t));
if (hostname_len == 0 ||
hostname_len  sizeof(hostname))
@@ -309,8 +316,17 @@ priv_init(char *conf, int numeric, int l
servname[servname_len - 1] = '\0';
 
memset(hints, 0, sizeof(hints));
-   hints.ai_family = AF_UNSPEC;
+   if (strcmp(protoname, udp) == 0) {
+   hints.ai_family = AF_UNSPEC;
+   } else if (strcmp(protoname, udp4) == 0) {
+   hints.ai_family = AF_INET;
+   } else if (strcmp(protoname, udp6) == 0) {
+   hints.ai_family = AF_INET6;
+   } else {
+   errx(1, unknown protocol %s, protoname);
+   }
hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_protocol = IPPROTO_UDP;
i = getaddrinfo(hostname, servname, hints, res0);
if (i != 0 || res0 == NULL) {
addr_len = 0;
@@ -661,25 +677,30 @@ priv_config_parse_done(void)
 /* Name/service to address translation.  Response is placed into addr.
  * Return 0 for success or  0 for error like getaddrinfo(3) */
 int
-priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
+priv_getaddrinfo(char *proto, char *host, char *serv, struct sockaddr *addr,
 size_t addr_len)
 {
-   char hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
+   char protocpy[5], hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
int cmd, ret_len;
-   size_t hostname_len, servname_len;
+   size_t protoname_len, hostname_len, servname_len;
 
if (priv_fd  0)
errx(1, %s: called from privileged portion, __func__);
 
-   if (strlcpy(hostcpy, host, sizeof hostcpy) = sizeof(hostcpy))
+   if (strlcpy(protocpy, proto, sizeof(protocpy)) = sizeof(protocpy))
+   errx(1, %s: overflow attempt in protoname, __func__);
+   protoname_len = strlen(protocpy) + 1;
+   if (strlcpy(hostcpy, host, sizeof(hostcpy)) = sizeof(hostcpy))
errx(1, %s: overflow attempt in hostname, __func__);
hostname_len = strlen(hostcpy) + 1;
-   if (strlcpy(servcpy, serv, sizeof servcpy) = sizeof(servcpy))
+   if (strlcpy(servcpy, serv, sizeof(servcpy)) = sizeof(servcpy))
errx(1, %s: overflow attempt in servname, __func__);
servname_len = strlen(servcpy) + 1;
 
cmd = PRIV_GETADDRINFO;
must_write(priv_fd, cmd, sizeof(int));
+   must_write(priv_fd, protoname_len, sizeof(size_t));
+   must_write(priv_fd, protocpy, protoname_len);

Re: syslogd ipv6 proto6

2014-08-22 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

At the moment syslogd opens both IPv4 and IPv6 sockets unconditionally.
I can restrict it to a protocol family with -4 and -6 command line
switches.  If the log server is a FQDN, DNS chosses wether to take
the IPv4 or IPv6 route.  For that I have invented a udp4:// or
udp6:// prefix to choose a protocol.  This syntax was chosen as I
want to extend it to tcp:// and tls:// later.

Do we want such IPv4/IPv6 knobs?

ok?

bluhm

? usr.sbin/syslogd/obj
Index: usr.sbin/syslogd/privsep.c
===
RCS file: /cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.40
diff -u -p -r1.40 privsep.c
--- usr.sbin/syslogd/privsep.c  21 Aug 2014 17:00:34 -  1.40
+++ usr.sbin/syslogd/privsep.c  22 Aug 2014 16:31:08 -
@@ -101,8 +101,8 @@ int
 priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
 {
int i, fd, socks[2], cmd, addr_len, result, restart;
-   size_t path_len, hostname_len, servname_len;
-   char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN];
+   size_t path_len, protoname_len, hostname_len, servname_len;
+   char path[MAXPATHLEN], protoname[5], hostname[MAXHOSTNAMELEN];
char servname[NI_MAXSERV];
struct sockaddr_storage addr;
struct stat cf_stat;
@@ -293,7 +293,14 @@ priv_init(char *conf, int numeric, int l
 
case PRIV_GETADDRINFO:
dprintf([priv]: msg PRIV_GETADDRINFO received\n);
-   /* Expecting: len, hostname, len, servname */
+   /* Expecting: len, proto, len, host, len, serv */
+   must_read(socks[0], protoname_len, sizeof(size_t));
+   if (protoname_len == 0 ||
+   protoname_len  sizeof(protoname))
+   _exit(1);
+   must_read(socks[0], protoname, protoname_len);
+   protoname[protoname_len - 1] = '\0';
+
must_read(socks[0], hostname_len, sizeof(size_t));
if (hostname_len == 0 ||
hostname_len  sizeof(hostname))
@@ -309,8 +316,17 @@ priv_init(char *conf, int numeric, int l
servname[servname_len - 1] = '\0';
 
memset(hints, 0, sizeof(hints));
-   hints.ai_family = AF_UNSPEC;
+   if (strcmp(protoname, udp) == 0) {
+   hints.ai_family = AF_UNSPEC;
+   } else if (strcmp(protoname, udp4) == 0) {
+   hints.ai_family = AF_INET;
+   } else if (strcmp(protoname, udp6) == 0) {
+   hints.ai_family = AF_INET6;
+   } else {
+   errx(1, unknown protocol %s, protoname);
+   }
hints.ai_socktype = SOCK_DGRAM;
+   hints.ai_protocol = IPPROTO_UDP;
i = getaddrinfo(hostname, servname, hints, res0);
if (i != 0 || res0 == NULL) {
addr_len = 0;
@@ -661,25 +677,30 @@ priv_config_parse_done(void)
 /* Name/service to address translation.  Response is placed into addr.
  * Return 0 for success or  0 for error like getaddrinfo(3) */
 int
-priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
+priv_getaddrinfo(char *proto, char *host, char *serv, struct sockaddr *addr,
 size_t addr_len)
 {
-   char hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
+   char protocpy[5], hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
int cmd, ret_len;
-   size_t hostname_len, servname_len;
+   size_t protoname_len, hostname_len, servname_len;
 
if (priv_fd  0)
errx(1, %s: called from privileged portion, __func__);
 
-   if (strlcpy(hostcpy, host, sizeof hostcpy) = sizeof(hostcpy))
+   if (strlcpy(protocpy, proto, sizeof(protocpy)) = sizeof(protocpy))
+   errx(1, %s: overflow attempt in protoname, __func__);
+   protoname_len = strlen(protocpy) + 1;
+   if (strlcpy(hostcpy, host, sizeof(hostcpy)) = sizeof(hostcpy))
errx(1, %s: overflow attempt in hostname, __func__);
hostname_len = strlen(hostcpy) + 1;
-   if (strlcpy(servcpy, serv, sizeof servcpy) = sizeof(servcpy))
+   if (strlcpy(servcpy, serv, sizeof(servcpy)) = sizeof(servcpy))
errx(1, %s: overflow attempt in servname, __func__);
servname_len = strlen(servcpy) + 1;
 
cmd = PRIV_GETADDRINFO;
must_write(priv_fd, cmd, sizeof(int));
+   must_write(priv_fd, protoname_len, sizeof(size_t));
+   must_write(priv_fd, protocpy, protoname_len);
must_write(priv_fd, hostname_len, 

Re: syslogd ipv6 man5

2014-08-21 Thread Jason McIntyre
On Thu, Aug 21, 2014 at 01:39:55AM +0200, Alexander Bluhm wrote:
 On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
  I will split this diff into smaller parts to make review and
  discussion easier.
 
 Document square brackets for IPv6 addresses.  From FreeBSD.
 
 Index: usr.sbin/syslogd/syslog.conf.5
 ===
 RCS file: /cvs/src/usr.sbin/syslogd/syslog.conf.5,v
 retrieving revision 1.24
 diff -u -p -r1.24 syslog.conf.5
 --- usr.sbin/syslogd/syslog.conf.520 Jan 2014 05:07:48 -  1.24
 +++ usr.sbin/syslogd/syslog.conf.520 Aug 2014 23:36:16 -
 @@ -220,6 +220,13 @@ program on the named host.
  A port number may be optionally specified using the
  .Ar host:port
  syntax.
 +IPv6 addresses can be used by surrounding the address portion with
 +square brackets
 +.Po
 +.Ql [\
 +and
 +.Ql ]\
 +.Pc .
  .It
  A comma separated list of users.
  Selected messages are written to those users
 

it'd be simpler to use just 

...
square brackets
.Qq [] .

jmc



Re: syslogd ipv6 hostportlen

2014-08-21 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Instead of getting a nasty error message from privsep
syslogd: priv_getaddrinfo: overflow attempt in hostname
check the host and port length when parsing the config.

ok?

bluhm

Index: usr.sbin/syslogd/syslogd.c
===
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.116
diff -u -p -r1.116 syslogd.c
--- usr.sbin/syslogd/syslogd.c  21 Aug 2014 17:00:34 -  1.116
+++ usr.sbin/syslogd/syslogd.c  21 Aug 2014 20:10:41 -
@@ -1547,8 +1547,21 @@ cfline(char *line, char *prog)
logerror(ebuf);
break;
}
-   if (priv_getaddrinfo(host,
-   port == NULL ? syslog : port,
+   if (strlen(host) = MAXHOSTNAMELEN) {
+   snprintf(ebuf, sizeof(ebuf), host too long \%s\,
+   f-f_un.f_forw.f_loghost);
+   logerror(ebuf);
+   break;
+   }
+   if (port == NULL)
+   port = syslog;
+   if (strlen(port) = NI_MAXSERV) {
+   snprintf(ebuf, sizeof(ebuf), port too long \%s\,
+   f-f_un.f_forw.f_loghost);
+   logerror(ebuf);
+   break;
+   }
+   if (priv_getaddrinfo(host, port,
(struct sockaddr*)f-f_un.f_forw.f_addr,
sizeof(f-f_un.f_forw.f_addr)) != 0) {
snprintf(ebuf, sizeof(ebuf), bad hostname \%s\,



Re: syslogd ipv6 getnameinfo

2014-08-20 Thread Jérémie Courrèges-Anglas
Alexander Bluhm alexander.bl...@gmx.net writes:

 On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

 Replace gethostbyaddr(3) with getnameinfo(3).

 Note that I remove the sigprocmask() that was added in rev 1.23
 before privsep.  It was necessary because gethostbyaddr() is not
 signal safe.

 ok?

ok.

Could you please update the comments about the return values of
priv_get(addr|name)info?

[...]

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: syslogd ipv6 socket

2014-08-20 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Send and receive UDP syslog packets on the IPv6 socket.

ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===
RCS file: /cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.38
diff -u -p -r1.38 privsep.c
--- usr.sbin/syslogd/privsep.c  20 Aug 2014 20:10:17 -  1.38
+++ usr.sbin/syslogd/privsep.c  20 Aug 2014 23:16:41 -
@@ -177,6 +177,8 @@ priv_init(char *conf, int numeric, int l
close(pfd[PFD_UNIX_0 + i].fd);
if (pfd[PFD_INET].fd != -1)
close(pfd[PFD_INET].fd);
+   if (pfd[PFD_INET6].fd != -1)
+   close(pfd[PFD_INET6].fd);
if (pfd[PFD_CTLSOCK].fd != -1)
close(pfd[PFD_CTLSOCK].fd);
if (pfd[PFD_CTLCONN].fd != -1)
@@ -306,8 +308,8 @@ priv_init(char *conf, int numeric, int l
must_read(socks[0], servname, servname_len);
servname[servname_len - 1] = '\0';
 
-   memset(hints, '\0', sizeof(hints));
-   hints.ai_family = AF_INET;
+   memset(hints, 0, sizeof(hints));
+   hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
i = getaddrinfo(hostname, servname, hints, res0);
if (i != 0 || res0 == NULL) {
Index: usr.sbin/syslogd/syslogd.c
===
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.114
diff -u -p -r1.114 syslogd.c
--- usr.sbin/syslogd/syslogd.c  20 Aug 2014 20:10:17 -  1.114
+++ usr.sbin/syslogd/syslogd.c  20 Aug 2014 23:16:42 -
@@ -188,7 +188,6 @@ int Debug;  /* debug flag */
 intStartup = 1;/* startup flag */
 char   LocalHostName[MAXHOSTNAMELEN];  /* our hostname */
 char   *LocalDomain;   /* our local domain name */
-intInetInuse = 0;  /* non-zero if INET sockets are being used */
 intInitialized = 0;/* set when we have initialized ourselves */
 
 intMarkInterval = 20 * 60; /* interval between marks in seconds */
@@ -282,7 +281,7 @@ main(int argc, char *argv[])
 {
int ch, i, linesize, fd;
struct sockaddr_un fromunix;
-   struct sockaddr_in frominet;
+   struct sockaddr_storage from;
socklen_t len;
char *p, *line;
char resolve[MAXHOSTNAMELEN];
@@ -369,7 +368,7 @@ main(int argc, char *argv[])
}
 
memset(hints, 0, sizeof(hints));
-   hints.ai_family = AF_INET;
+   hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE;
@@ -384,13 +383,14 @@ main(int argc, char *argv[])
for (res = res0; res; res = res-ai_next) {
struct pollfd *pfdp;
 
-   if (res-ai_family == AF_INET)
+   switch (res-ai_family) {
+   case AF_INET:
pfdp = pfd[PFD_INET];
-   else {
-   /*
-* XXX AF_INET6 is skipped on purpose, need to
-* fix '@' handling first.
-*/
+   break;
+   case AF_INET6:
+   pfdp = pfd[PFD_INET6];
+   break;
+   default:
continue;
}
 
@@ -410,7 +410,6 @@ main(int argc, char *argv[])
continue;
}
 
-   InetInuse = 1;
pfdp-fd = fd;
if (SecureMode)
shutdown(pfdp-fd, SHUT_RD);
@@ -582,18 +581,31 @@ main(int argc, char *argv[])
}
}
if ((pfd[PFD_INET].revents  POLLIN) != 0) {
-   len = sizeof(frominet);
+   len = sizeof(from);
i = recvfrom(pfd[PFD_INET].fd, line, MAXLINE, 0,
-   (struct sockaddr *)frominet, len);
+   (struct sockaddr *)from, len);
if (i  0) {
line[i] = '\0';
-   cvthname((struct sockaddr *)frominet, resolve,
-   sizeof resolve);
+   cvthname((struct sockaddr *)from, resolve,
+   sizeof(resolve));
dprintf(cvthname res: %s\n, resolve);
printline(resolve, line);
} else if (i  0  errno != EINTR)
logerror(recvfrom inet);
}
+   if ((pfd[PFD_INET6].revents  POLLIN) != 0) {
+ 

Re: syslogd ipv6 man5

2014-08-20 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Document square brackets for IPv6 addresses.  From FreeBSD.

Index: usr.sbin/syslogd/syslog.conf.5
===
RCS file: /cvs/src/usr.sbin/syslogd/syslog.conf.5,v
retrieving revision 1.24
diff -u -p -r1.24 syslog.conf.5
--- usr.sbin/syslogd/syslog.conf.5  20 Jan 2014 05:07:48 -  1.24
+++ usr.sbin/syslogd/syslog.conf.5  20 Aug 2014 23:36:16 -
@@ -220,6 +220,13 @@ program on the named host.
 A port number may be optionally specified using the
 .Ar host:port
 syntax.
+IPv6 addresses can be used by surrounding the address portion with
+square brackets
+.Po
+.Ql [\
+and
+.Ql ]\
+.Pc .
 .It
 A comma separated list of users.
 Selected messages are written to those users



Re: syslogd ipv6 getnameinfo

2014-08-19 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Replace gethostbyaddr(3) with getnameinfo(3).

Note that I remove the sigprocmask() that was added in rev 1.23
before privsep.  It was necessary because gethostbyaddr() is not
signal safe.

ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.36
diff -u -p -u -p -r1.36 privsep.c
--- usr.sbin/syslogd/privsep.c  19 Aug 2014 00:53:01 -  1.36
+++ usr.sbin/syslogd/privsep.c  19 Aug 2014 20:01:12 -
@@ -68,7 +68,7 @@ enum cmd_types {
PRIV_OPEN_CONFIG,   /* open config file for reading only */
PRIV_CONFIG_MODIFIED,   /* check if config file has been modified */
PRIV_GETHOSTSERV,   /* resolve host/service names */
-   PRIV_GETHOSTBYADDR, /* resolve numeric address into hostname */
+   PRIV_GETNAMEINFO,   /* resolve numeric address into hostname */
PRIV_DONE_CONFIG_PARSE  /* signal that the initial config parse is done 
*/
 };
 
@@ -76,7 +76,7 @@ static int priv_fd = -1;
 static volatile pid_t child_pid = -1;
 static char config_file[MAXPATHLEN];
 static struct stat cf_info;
-static int allow_gethostbyaddr = 0;
+static int allow_getnameinfo = 0;
 static volatile sig_atomic_t cur_state = STATE_INIT;
 
 /* Queue for the allowed logfiles */
@@ -100,12 +100,12 @@ static int  may_read(int, void *, size_t
 int
 priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[])
 {
-   int i, fd, socks[2], cmd, addr_len, addr_af, result, restart;
+   int i, fd, socks[2], cmd, addr_len, result, restart;
size_t path_len, hostname_len, servname_len;
char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN];
char servname[MAXHOSTNAMELEN];
+   struct sockaddr_storage addr;
struct stat cf_stat;
-   struct hostent *hp;
struct passwd *pw;
struct addrinfo hints, *res0;
struct sigaction sa;
@@ -191,11 +191,11 @@ priv_init(char *conf, int numeric, int l
if (stat(config_file, cf_info)  0)
err(1, stat config file failed);
 
-   /* Save whether or not the child can have access to gethostbyaddr(3) */
+   /* Save whether or not the child can have access to getnameinfo(3) */
if (numeric  0)
-   allow_gethostbyaddr = 0;
+   allow_getnameinfo = 0;
else
-   allow_gethostbyaddr = 1;
+   allow_getnameinfo = 1;
 
TAILQ_INIT(lognames);
increase_state(STATE_CONFIG);
@@ -320,24 +320,24 @@ priv_init(char *conf, int numeric, int l
}
break;
 
-   case PRIV_GETHOSTBYADDR:
-   dprintf([priv]: msg PRIV_GETHOSTBYADDR received\n);
-   if (!allow_gethostbyaddr)
-   errx(1, rejected attempt to gethostbyaddr);
-   /* Expecting: length, address, address family */
+   case PRIV_GETNAMEINFO:
+   dprintf([priv]: msg PRIV_GETNAMEINFO received\n);
+   if (!allow_getnameinfo)
+   errx(1, rejected attempt to getnameinfo);
+   /* Expecting: length, sockaddr */
must_read(socks[0], addr_len, sizeof(int));
-   if (addr_len = 0 || addr_len  sizeof(hostname))
+   if (addr_len = 0 || addr_len  sizeof(addr))
_exit(1);
-   must_read(socks[0], hostname, addr_len);
-   must_read(socks[0], addr_af, sizeof(int));
-   hp = gethostbyaddr(hostname, addr_len, addr_af);
-   if (hp == NULL) {
+   must_read(socks[0], addr, addr_len);
+   if (getnameinfo((struct sockaddr *)addr, addr_len,
+   hostname, sizeof(hostname), NULL, 0,
+   NI_NOFQDN|NI_NAMEREQD|NI_DGRAM) != 0) {
addr_len = 0;
must_write(socks[0], addr_len, sizeof(int));
} else {
-   addr_len = strlen(hp-h_name) + 1;
+   addr_len = strlen(hostname) + 1;
must_write(socks[0], addr_len, sizeof(int));
-   must_write(socks[0], hp-h_name, addr_len);
+   must_write(socks[0], hostname, addr_len);
}
break;
default:
@@ -702,33 +702,33 @@ priv_gethostserv(char *host, char *serv,
 /* Reverse address resolution; response is placed into res, and length of
  * response is returned (zero on error) */
 int

Re: syslogd ipv6 getaddrinfo

2014-08-19 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Rename priv_gethostserv() to priv_getaddrinfo() as this is what the
function does.  Change the return code semantics to match getaddrinfo(3).

ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.36
diff -u -p -u -p -r1.36 privsep.c
--- usr.sbin/syslogd/privsep.c  19 Aug 2014 00:53:01 -  1.36
+++ usr.sbin/syslogd/privsep.c  19 Aug 2014 21:06:35 -
@@ -67,7 +67,7 @@ enum cmd_types {
PRIV_OPEN_UTMP, /* open utmp for reading only */
PRIV_OPEN_CONFIG,   /* open config file for reading only */
PRIV_CONFIG_MODIFIED,   /* check if config file has been modified */
-   PRIV_GETHOSTSERV,   /* resolve host/service names */
+   PRIV_GETADDRINFO,   /* resolve host/service names */
PRIV_GETHOSTBYADDR, /* resolve numeric address into hostname */
PRIV_DONE_CONFIG_PARSE  /* signal that the initial config parse is done 
*/
 };
@@ -289,17 +289,19 @@ priv_init(char *conf, int numeric, int l
increase_state(STATE_RUNNING);
break;
 
-   case PRIV_GETHOSTSERV:
-   dprintf([priv]: msg PRIV_GETHOSTSERV received\n);
+   case PRIV_GETADDRINFO:
+   dprintf([priv]: msg PRIV_GETADDRINFO received\n);
/* Expecting: len, hostname, len, servname */
must_read(socks[0], hostname_len, sizeof(size_t));
-   if (hostname_len == 0 || hostname_len  
sizeof(hostname))
+   if (hostname_len == 0 ||
+   hostname_len  sizeof(hostname))
_exit(1);
must_read(socks[0], hostname, hostname_len);
hostname[hostname_len - 1] = '\0';
 
must_read(socks[0], servname_len, sizeof(size_t));
-   if (servname_len == 0 || servname_len  
sizeof(servname))
+   if (servname_len == 0 ||
+   servname_len  sizeof(servname))
_exit(1);
must_read(socks[0], servname, servname_len);
servname[servname_len - 1] = '\0';
@@ -657,7 +659,7 @@ priv_config_parse_done(void)
 /* Name/service to address translation.  Response is placed into addr, and
  * the length is returned (zero on error) */
 int
-priv_gethostserv(char *host, char *serv, struct sockaddr *addr,
+priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
 size_t addr_len)
 {
char hostcpy[MAXHOSTNAMELEN], servcpy[MAXHOSTNAMELEN];
@@ -674,7 +676,7 @@ priv_gethostserv(char *host, char *serv,
errx(1, %s: overflow attempt in servname, __func__);
servname_len = strlen(servcpy) + 1;
 
-   cmd = PRIV_GETHOSTSERV;
+   cmd = PRIV_GETADDRINFO;
must_write(priv_fd, cmd, sizeof(int));
must_write(priv_fd, hostname_len, sizeof(size_t));
must_write(priv_fd, hostcpy, hostname_len);
@@ -686,7 +688,7 @@ priv_gethostserv(char *host, char *serv,
 
/* Check there was no error (indicated by a return of 0) */
if (!ret_len)
-   return 0;
+   return (-1);
 
/* Make sure we aren't overflowing the passed in buffer */
if (addr_len  ret_len)
@@ -696,7 +698,7 @@ priv_gethostserv(char *host, char *serv,
memset(addr, '\0', addr_len);
must_read(priv_fd, addr, ret_len);
 
-   return ret_len;
+   return (0);
 }
 
 /* Reverse address resolution; response is placed into res, and length of
Index: usr.sbin/syslogd/syslogd.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.112
diff -u -p -u -p -r1.112 syslogd.c
--- usr.sbin/syslogd/syslogd.c  19 Aug 2014 00:24:00 -  1.112
+++ usr.sbin/syslogd/syslogd.c  19 Aug 2014 21:09:15 -
@@ -1427,7 +1427,7 @@ find_dup(struct filed *f)
 struct filed *
 cfline(char *line, char *prog)
 {
-   int i, pri, addr_len;
+   int i, pri;
size_t rb_len;
char *bp, *p, *q, *cp;
char buf[MAXLINE], ebuf[100];
@@ -1538,11 +1538,10 @@ cfline(char *line, char *prog)
logerror(ebuf);
break;
}
-   addr_len = priv_gethostserv(f-f_un.f_forw.f_hname,
+   if (priv_getaddrinfo(f-f_un.f_forw.f_hname,
cp == NULL ? syslog : cp,
-   (struct sockaddr*)f-f_un.f_forw.f_addr,
-   sizeof(f-f_un.f_forw.f_addr));
-   if (addr_len  1) {
+   (struct sockaddr 

Re: syslogd ipv6

2014-08-18 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Let's start with the easy part, fix trailing white spaces.

ok?

bluhm

Index: usr.sbin/syslogd/syslogd.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.111
diff -u -p -u -p -r1.111 syslogd.c
--- usr.sbin/syslogd/syslogd.c  14 Jul 2014 04:02:33 -  1.111
+++ usr.sbin/syslogd/syslogd.c  19 Aug 2014 00:00:14 -
@@ -1014,7 +1014,7 @@ fprintlog(struct filed *f, int flags, ch
case F_MEMBUF:
dprintf(\n);
snprintf(line, sizeof(line), %.15s %s %s,
-   (char *)iov[0].iov_base, (char *)iov[2].iov_base, 
+   (char *)iov[0].iov_base, (char *)iov[2].iov_base,
(char *)iov[4].iov_base);
if (ringbuf_append_line(f-f_un.f_mb.f_rb, line) == 1)
f-f_un.f_mb.f_overflow = 1;
@@ -1538,9 +1538,9 @@ cfline(char *line, char *prog)
logerror(ebuf);
break;
}
-   addr_len = priv_gethostserv(f-f_un.f_forw.f_hname, 
-   cp == NULL ? syslog : cp, 
-   (struct sockaddr*)f-f_un.f_forw.f_addr, 
+   addr_len = priv_gethostserv(f-f_un.f_forw.f_hname,
+   cp == NULL ? syslog : cp,
+   (struct sockaddr*)f-f_un.f_forw.f_addr,
sizeof(f-f_un.f_forw.f_addr));
if (addr_len  1) {
snprintf(ebuf, sizeof(ebuf), bad hostname \%s\, p);


pgpFDZFMnCUDS.pgp
Description: PGP signature


Re: syslogd ipv6

2014-08-18 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

Replace manually written function names with __func__.  This
will make renaming functions easier.

ok?

bluhm


Index: usr.sbin/syslogd/privsep.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.34
diff -u -p -u -p -r1.34 privsep.c
--- usr.sbin/syslogd/privsep.c  23 Nov 2008 04:29:42 -  1.34
+++ usr.sbin/syslogd/privsep.c  19 Aug 2014 00:03:18 -
@@ -531,7 +531,7 @@ priv_open_tty(const char *tty)
size_t path_len;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged portion, priv_open_tty);
+   errx(1, %s: called from privileged portion, __func__);
 
if (strlcpy(path, tty, sizeof path) = sizeof(path))
return -1;
@@ -554,7 +554,7 @@ priv_open_log(const char *lognam)
size_t path_len;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged child, priv_open_log);
+   errx(1, %s: called from privileged child, __func__);
 
if (strlcpy(path, lognam, sizeof path) = sizeof(path))
return -1;
@@ -579,7 +579,7 @@ priv_open_utmp(void)
FILE *fp;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged portion, priv_open_utmp);
+   errx(1, %s: called from privileged portion, __func__);
 
cmd = PRIV_OPEN_UTMP;
must_write(priv_fd, cmd, sizeof(int));
@@ -605,7 +605,7 @@ priv_open_config(void)
FILE *fp;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged portion, 
priv_open_config);
+   errx(1, %s: called from privileged portion, __func__);
 
cmd = PRIV_OPEN_CONFIG;
must_write(priv_fd, cmd, sizeof(int));
@@ -630,8 +630,7 @@ priv_config_modified(void)
int cmd, res;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged portion,
-   priv_config_modified);
+   errx(1, %s: called from privileged portion, __func__);
 
cmd = PRIV_CONFIG_MODIFIED;
must_write(priv_fd, cmd, sizeof(int));
@@ -649,8 +648,7 @@ priv_config_parse_done(void)
int cmd;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged portion,
-   priv_config_parse_done);
+   errx(1, %s: called from privileged portion, __func__);
 
cmd = PRIV_DONE_CONFIG_PARSE;
must_write(priv_fd, cmd, sizeof(int));
@@ -667,13 +665,13 @@ priv_gethostserv(char *host, char *serv,
size_t hostname_len, servname_len;
 
if (priv_fd  0)
-   errx(1, %s: called from privileged portion, 
priv_gethostserv);
+   errx(1, %s: called from privileged portion, __func__);
 
if (strlcpy(hostcpy, host, sizeof hostcpy) = sizeof(hostcpy))
-   errx(1, %s: overflow attempt in hostname, priv_gethostserv);
+   errx(1, %s: overflow attempt in hostname, __func__);
hostname_len = strlen(hostcpy) + 1;
if (strlcpy(servcpy, serv, sizeof servcpy) = sizeof(servcpy))
-   errx(1, %s: overflow attempt in servname, priv_gethostserv);
+   errx(1, %s: overflow attempt in servname, __func__);
servname_len = strlen(servcpy) + 1;
 
cmd = PRIV_GETHOSTSERV;
@@ -692,7 +690,7 @@ priv_gethostserv(char *host, char *serv,
 
/* Make sure we aren't overflowing the passed in buffer */
if (addr_len  ret_len)
-   errx(1, %s: overflow attempt in return, priv_gethostserv);
+   errx(1, %s: overflow attempt in return, __func__);
 
/* Read the resolved address and make sure we got all of it */
memset(addr, '\0', addr_len);
@@ -709,7 +707,7 @@ priv_gethostbyaddr(char *addr, int addr_
int cmd, ret_len;
 
if (priv_fd  0)
-   errx(1, %s called from privileged portion, 
priv_gethostbyaddr);
+   errx(1, %s called from privileged portion, __func__);
 
cmd = PRIV_GETHOSTBYADDR;
must_write(priv_fd, cmd, sizeof(int));
@@ -726,7 +724,7 @@ priv_gethostbyaddr(char *addr, int addr_
 
/* Check we don't overflow the passed in buffer */
if (res_len  ret_len)
-   errx(1, %s: overflow attempt in return, priv_gethostbyaddr);
+   errx(1, %s: overflow attempt in return, __func__);
 
/* Read the resolved hostname */
must_read(priv_fd, res, ret_len);


pgptuhErI0rG1.pgp
Description: PGP signature


Re: syslogd ipv6

2014-08-18 Thread Alexander Bluhm
On Tue, Aug 19, 2014 at 01:59:42AM +0200, Alexander Bluhm wrote:
 I will split this diff into smaller parts to make review and
 discussion easier.

The exit codes in privsep.c seem to be the wrong way around.  Fatal
errors should exit with 1, and regular shutdown should result in
exit with 0.  I have written a syslogd regression test that gets
confused by the current behavior.

ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.34
diff -u -p -u -p -r1.34 privsep.c
--- usr.sbin/syslogd/privsep.c  23 Nov 2008 04:29:42 -  1.34
+++ usr.sbin/syslogd/privsep.c  19 Aug 2014 00:07:08 -
@@ -210,7 +210,7 @@ priv_init(char *conf, int numeric, int l
/* Expecting: length, path */
must_read(socks[0], path_len, sizeof(size_t));
if (path_len == 0 || path_len  sizeof(path))
-   _exit(0);
+   _exit(1);
must_read(socks[0], path, path_len);
path[path_len - 1] = '\0';
check_tty_name(path, path_len);
@@ -229,7 +229,7 @@ priv_init(char *conf, int numeric, int l
/* Expecting: length, path */
must_read(socks[0], path_len, sizeof(size_t));
if (path_len == 0 || path_len  sizeof(path))
-   _exit(0);
+   _exit(1);
must_read(socks[0], path, path_len);
path[path_len - 1] = '\0';
check_log_name(path, path_len);
@@ -294,13 +294,13 @@ priv_init(char *conf, int numeric, int l
/* Expecting: len, hostname, len, servname */
must_read(socks[0], hostname_len, sizeof(size_t));
if (hostname_len == 0 || hostname_len  
sizeof(hostname))
-   _exit(0);
+   _exit(1);
must_read(socks[0], hostname, hostname_len);
hostname[hostname_len - 1] = '\0';
 
must_read(socks[0], servname_len, sizeof(size_t));
if (servname_len == 0 || servname_len  
sizeof(servname))
-   _exit(0);
+   _exit(1);
must_read(socks[0], servname, servname_len);
servname[servname_len - 1] = '\0';
 
@@ -327,7 +327,7 @@ priv_init(char *conf, int numeric, int l
/* Expecting: length, address, address family */
must_read(socks[0], addr_len, sizeof(int));
if (addr_len = 0 || addr_len  sizeof(hostname))
-   _exit(0);
+   _exit(1);
must_read(socks[0], hostname, addr_len);
must_read(socks[0], addr_af, sizeof(int));
hp = gethostbyaddr(hostname, addr_len, addr_af);
@@ -362,7 +362,7 @@ priv_init(char *conf, int numeric, int l
execvp(argv[0], argv);
}
unlink(_PATH_LOGPID);
-   _exit(1);
+   _exit(0);
 }
 
 static int
@@ -797,7 +797,7 @@ must_read(int fd, void *buf, size_t n)
if (errno == EINTR || errno == EAGAIN)
continue;
case 0:
-   _exit(0);
+   _exit(1);
default:
pos += res;
}
@@ -819,7 +819,7 @@ must_write(int fd, void *buf, size_t n)
if (errno == EINTR || errno == EAGAIN)
continue;
case 0:
-   _exit(0);
+   _exit(1);
default:
pos += res;
}