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.
Parse loghost in a separate function. Allow [] around hostname,
needed for IPv6 addresses. Print full loghost specifier in case
of error or debug. Make string sizes more precise.
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 -0000 1.38
+++ usr.sbin/syslogd/privsep.c 20 Aug 2014 22:34:24 -0000
@@ -103,7 +103,7 @@ priv_init(char *conf, int numeric, int l
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];
+ char servname[NI_MAXSERV];
struct sockaddr_storage addr;
struct stat cf_stat;
struct passwd *pw;
@@ -662,7 +662,7 @@ int
priv_getaddrinfo(char *host, char *serv, struct sockaddr *addr,
size_t addr_len)
{
- char hostcpy[MAXHOSTNAMELEN], servcpy[MAXHOSTNAMELEN];
+ char hostcpy[MAXHOSTNAMELEN], servcpy[NI_MAXSERV];
int cmd, ret_len;
size_t hostname_len, servname_len;
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 -0000 1.114
+++ usr.sbin/syslogd/syslogd.c 20 Aug 2014 22:34:24 -0000
@@ -127,7 +127,8 @@ struct filed {
union {
char f_uname[MAXUNAMES][UT_NAMESIZE+1];
struct {
- char f_hname[MAXHOSTNAMELEN];
+ char f_loghost[1+2+MAXHOSTNAMELEN+1+NI_MAXSERV];
+ /* @[hostname]:servname */
struct sockaddr_storage f_addr;
} f_forw; /* forwarding address */
char f_fname[MAXPATHLEN];
@@ -268,6 +269,7 @@ void reapchild(int);
char *ttymsg(struct iovec *, int, char *, int);
void usage(void);
void wallmsg(struct filed *, struct iovec *);
+int loghost(char *, char **, char **);
int getmsgbufsize(void);
int unix_socket(char *, int, mode_t);
void double_rbuf(int);
@@ -905,7 +907,7 @@ fprintlog(struct filed *f, int flags, ch
break;
case F_FORW:
- dprintf(" %s\n", f->f_un.f_forw.f_hname);
+ dprintf(" %s\n", f->f_un.f_forw.f_loghost);
if ((l = snprintf(line, sizeof(line), "<%d>%.15s %s%s%s",
f->f_prevpri, (char *)iov[0].iov_base,
IncludeHostname ? LocalHostName : "",
@@ -1349,7 +1351,7 @@ init(void)
break;
case F_FORW:
- printf("%s", f->f_un.f_forw.f_hname);
+ printf("%s", f->f_un.f_forw.f_loghost);
break;
case F_USERS:
@@ -1411,7 +1413,7 @@ cfline(char *line, char *prog)
{
int i, pri;
size_t rb_len;
- char *bp, *p, *q, *cp;
+ char *bp, *p, *q, *host, *port;
char buf[MAXLINE], ebuf[100];
struct filed *xf, *f, *d;
@@ -1510,21 +1512,26 @@ cfline(char *line, char *prog)
case '@':
if (!InetInuse)
break;
- if ((cp = strrchr(++p, ':')) != NULL)
- *cp++ = '\0';
- if ((strlcpy(f->f_un.f_forw.f_hname, p,
- sizeof(f->f_un.f_forw.f_hname)) >=
- sizeof(f->f_un.f_forw.f_hname))) {
- snprintf(ebuf, sizeof(ebuf), "hostname too long \"%s\"",
+ if ((strlcpy(f->f_un.f_forw.f_loghost, p,
+ sizeof(f->f_un.f_forw.f_loghost)) >=
+ sizeof(f->f_un.f_forw.f_loghost))) {
+ snprintf(ebuf, sizeof(ebuf), "loghost too long \"%s\"",
p);
logerror(ebuf);
break;
}
- if (priv_getaddrinfo(f->f_un.f_forw.f_hname,
- cp == NULL ? "syslog" : cp,
- (struct sockaddr *)&f->f_un.f_forw.f_addr,
+ if (loghost(++p, &host, &port) == -1) {
+ snprintf(ebuf, sizeof(ebuf), "bad loghost \"%s\"",
+ f->f_un.f_forw.f_loghost);
+ logerror(ebuf);
+ break;
+ }
+ if (priv_getaddrinfo(host,
+ port == NULL ? "syslog" : 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\"", p);
+ snprintf(ebuf, sizeof(ebuf), "bad hostname \"%s\"",
+ f->f_un.f_forw.f_loghost);
logerror(ebuf);
break;
}
@@ -1633,6 +1640,26 @@ cfline(char *line, char *prog)
return (f);
}
+/*
+ * Parse the host and port parts from a loghost string.
+ */
+int
+loghost(char *str, char **host, char **port)
+{
+ *host = str;
+ if (**host == '[') {
+ (*host)++;
+ str = strchr(*host, ']');
+ if (str == NULL)
+ return (-1);
+ *str++ = '\0';
+ }
+ *port = strrchr(str, ':');
+ if (*port != NULL)
+ *(*port)++ = '\0';
+
+ return (0);
+}
/*
* Retrieve the size of the kernel message buffer, via sysctl.