mirror of
https://github.com/openbsd/src.git
synced 2024-12-22 16:42:56 -08:00
Allow to restrict syslogd to a protocol family with -4 and -6 command
line switches. If the log server is an FQDN, DNS chooses wether to take the IPv4 or IPv6 route. Allow to prefix the log host with udp4:// or udp6:// to choose a protocol. OK henning@
This commit is contained in:
parent
97e72a5119
commit
ad087aa9ef
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: privsep.c,v 1.41 2014/08/25 18:05:30 bluhm Exp $ */
|
||||
/* $OpenBSD: privsep.c,v 1.42 2014/08/25 18:19:18 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org>
|
||||
@ -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 lockfd, int nullfd, char *argv[])
|
||||
|
||||
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 lockfd, int nullfd, char *argv[])
|
||||
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, sizeof(size_t));
|
||||
must_write(priv_fd, hostcpy, hostname_len);
|
||||
must_write(priv_fd, &servname_len, sizeof(size_t));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: syslogd.c,v 1.118 2014/08/25 18:05:30 bluhm Exp $ */
|
||||
/* $OpenBSD: syslogd.c,v 1.119 2014/08/25 18:19:18 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1988, 1993, 1994
|
||||
@ -127,8 +127,8 @@ struct filed {
|
||||
union {
|
||||
char f_uname[MAXUNAMES][UT_NAMESIZE+1];
|
||||
struct {
|
||||
char f_loghost[1+1+MAXHOSTNAMELEN+1+NI_MAXSERV];
|
||||
/* @[hostname]:servname\0 */
|
||||
char f_loghost[1+4+3+1+MAXHOSTNAMELEN+1+NI_MAXSERV];
|
||||
/* @proto46://[hostname]:servname\0 */
|
||||
struct sockaddr_storage f_addr;
|
||||
} f_forw; /* forwarding address */
|
||||
char f_fname[MAXPATHLEN];
|
||||
@ -195,6 +195,8 @@ int MarkInterval = 20 * 60; /* interval between marks in seconds */
|
||||
int MarkSeq = 0; /* mark sequence number */
|
||||
int SecureMode = 1; /* when true, speak only unix domain socks */
|
||||
int NoDNS = 0; /* when true, will refrain from doing DNS lookups */
|
||||
int IPv4Only = 0; /* when true, disable IPv6 */
|
||||
int IPv6Only = 0; /* when true, disable IPv4 */
|
||||
int IncludeHostname = 0; /* include RFC 3164 style hostnames when forwarding */
|
||||
|
||||
char *ctlsock_path = NULL; /* Path to control socket */
|
||||
@ -268,7 +270,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 loghost(char *, char **, char **, char **);
|
||||
int getmsgbufsize(void);
|
||||
int unix_socket(char *, int, mode_t);
|
||||
void double_rbuf(int);
|
||||
@ -291,8 +293,16 @@ main(int argc, char *argv[])
|
||||
struct addrinfo hints, *res, *res0;
|
||||
FILE *fp;
|
||||
|
||||
while ((ch = getopt(argc, argv, "dhnuf:m:p:a:s:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "46dhnuf:m:p:a:s:")) != -1)
|
||||
switch (ch) {
|
||||
case '4': /* disable IPv6 */
|
||||
IPv4Only = 1;
|
||||
IPv6Only = 0;
|
||||
break;
|
||||
case '6': /* disable IPv4 */
|
||||
IPv6Only = 1;
|
||||
IPv4Only = 0;
|
||||
break;
|
||||
case 'd': /* debug */
|
||||
Debug++;
|
||||
break;
|
||||
@ -387,9 +397,13 @@ main(int argc, char *argv[])
|
||||
|
||||
switch (res->ai_family) {
|
||||
case AF_INET:
|
||||
if (IPv6Only)
|
||||
continue;
|
||||
pfdp = &pfd[PFD_INET];
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (IPv4Only)
|
||||
continue;
|
||||
pfdp = &pfd[PFD_INET6];
|
||||
break;
|
||||
default:
|
||||
@ -641,7 +655,7 @@ usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: syslogd [-dhnu] [-a path] [-f config_file] [-m mark_interval]\n"
|
||||
"usage: syslogd [-46dhnu] [-a path] [-f config_file] [-m mark_interval]\n"
|
||||
" [-p log_socket] [-s reporting_socket]\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -1437,7 +1451,7 @@ cfline(char *line, char *prog)
|
||||
{
|
||||
int i, pri;
|
||||
size_t rb_len;
|
||||
char *bp, *p, *q, *host, *port;
|
||||
char *bp, *p, *q, *proto, *host, *port;
|
||||
char buf[MAXLINE], ebuf[100];
|
||||
struct filed *xf, *f, *d;
|
||||
|
||||
@ -1542,12 +1556,39 @@ cfline(char *line, char *prog)
|
||||
logerror(ebuf);
|
||||
break;
|
||||
}
|
||||
if (loghost(++p, &host, &port) == -1) {
|
||||
if (loghost(++p, &proto, &host, &port) == -1) {
|
||||
snprintf(ebuf, sizeof(ebuf), "bad loghost \"%s\"",
|
||||
f->f_un.f_forw.f_loghost);
|
||||
logerror(ebuf);
|
||||
break;
|
||||
}
|
||||
if (proto == NULL)
|
||||
proto = "udp";
|
||||
if (strcmp(proto, "udp") == 0) {
|
||||
if (pfd[PFD_INET].fd == -1)
|
||||
proto = "udp6";
|
||||
if (pfd[PFD_INET6].fd == -1)
|
||||
proto = "udp4";
|
||||
} else if (strcmp(proto, "udp4") == 0) {
|
||||
if (pfd[PFD_INET].fd == -1) {
|
||||
snprintf(ebuf, sizeof(ebuf), "no udp4 \"%s\"",
|
||||
f->f_un.f_forw.f_loghost);
|
||||
logerror(ebuf);
|
||||
break;
|
||||
}
|
||||
} else if (strcmp(proto, "udp6") == 0) {
|
||||
if (pfd[PFD_INET6].fd == -1) {
|
||||
snprintf(ebuf, sizeof(ebuf), "no udp6 \"%s\"",
|
||||
f->f_un.f_forw.f_loghost);
|
||||
logerror(ebuf);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
snprintf(ebuf, sizeof(ebuf), "bad protocol \"%s\"",
|
||||
f->f_un.f_forw.f_loghost);
|
||||
logerror(ebuf);
|
||||
break;
|
||||
}
|
||||
if (strlen(host) >= MAXHOSTNAMELEN) {
|
||||
snprintf(ebuf, sizeof(ebuf), "host too long \"%s\"",
|
||||
f->f_un.f_forw.f_loghost);
|
||||
@ -1562,7 +1603,7 @@ cfline(char *line, char *prog)
|
||||
logerror(ebuf);
|
||||
break;
|
||||
}
|
||||
if (priv_getaddrinfo(host, port,
|
||||
if (priv_getaddrinfo(proto, 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\"",
|
||||
@ -1679,8 +1720,15 @@ cfline(char *line, char *prog)
|
||||
* Parse the host and port parts from a loghost string.
|
||||
*/
|
||||
int
|
||||
loghost(char *str, char **host, char **port)
|
||||
loghost(char *str, char **proto, char **host, char **port)
|
||||
{
|
||||
*proto = NULL;
|
||||
if ((*host = strchr(str, ':')) &&
|
||||
(*host)[1] == '/' && (*host)[2] == '/') {
|
||||
*proto = str;
|
||||
**host = '\0';
|
||||
str = *host + 3;
|
||||
}
|
||||
*host = str;
|
||||
if (**host == '[') {
|
||||
(*host)++;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: syslogd.h,v 1.11 2014/08/20 20:10:17 bluhm Exp $ */
|
||||
/* $OpenBSD: syslogd.h,v 1.12 2014/08/25 18:19:18 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org>
|
||||
@ -28,7 +28,7 @@ FILE *priv_open_utmp(void);
|
||||
FILE *priv_open_config(void);
|
||||
void priv_config_parse_done(void);
|
||||
int priv_config_modified(void);
|
||||
int priv_getaddrinfo(char *, char *, struct sockaddr *, size_t);
|
||||
int priv_getaddrinfo(char *, char *, char *, struct sockaddr *, size_t);
|
||||
int priv_getnameinfo(struct sockaddr *, socklen_t, char *, size_t);
|
||||
|
||||
/* Terminal message */
|
||||
|
Loading…
Reference in New Issue
Block a user