Re: syslogd ipv6 proto6
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
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
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
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
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
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
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
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
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
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
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
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
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
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; }