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.

Reply via email to