From: bluhm Date: Tue, 12 Jul 2016 09:47:25 +0000 (+0000) Subject: Add support for TLS client certificates in syslogd. This allows a X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ea1eb58efa7e567c5158b9dae86e23d07468dd9c;p=openbsd Add support for TLS client certificates in syslogd. This allows a remote server to verify that the log messages from our syslogd are authentic. From Kapetanakis Giannis; man page input jmc@; OK jung@ deraadt@ --- diff --git a/usr.sbin/syslogd/syslogd.8 b/usr.sbin/syslogd/syslogd.8 index cbd4cf71cc0..0c09aa17038 100644 --- a/usr.sbin/syslogd/syslogd.8 +++ b/usr.sbin/syslogd/syslogd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: syslogd.8,v 1.40 2016/03/31 15:53:25 schwarze Exp $ +.\" $OpenBSD: syslogd.8,v 1.41 2016/07/12 09:47:25 bluhm Exp $ .\" .\" Copyright (c) 1983, 1986, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -30,7 +30,7 @@ .\" from: @(#)syslogd.8 8.1 (Berkeley) 6/6/93 .\" $NetBSD: syslogd.8,v 1.3 1996/01/02 17:41:48 perry Exp $ .\" -.Dd $Mdocdate: March 31 2016 $ +.Dd $Mdocdate: July 12 2016 $ .Dt SYSLOGD 8 .Os .Sh NAME @@ -42,7 +42,9 @@ .Op Fl 46dFhnuV .Op Fl a Ar path .Op Fl C Ar CAfile +.Op Fl c Ar cert_file .Op Fl f Ar config_file +.Op Fl k Ar key_file .Op Fl m Ar mark_interval .Op Fl p Ar log_socket .Op Fl S Ar listen_address @@ -81,6 +83,11 @@ PEM encoded file containing CA certificates used for certificate validation; the default is .Pa /etc/ssl/cert.pem . +.It Fl c Ar cert_file +PEM encoded file containing the client certificate for TLS connections +to a remote host. +The default is not to use a client certificate for the connection +to a syslog server. .It Fl d Enable debugging to the standard output, and do not disassociate from the controlling terminal. @@ -93,6 +100,11 @@ the default is .Pa /etc/syslog.conf . .It Fl h Include the hostname when forwarding messages to a remote host. +.It Fl k Ar key_file +PEM encoded file containing the client private key for TLS connections +to a remote host. +This option has to be used together with +.Fl c Ar cert_file . .It Fl m Ar mark_interval Select the number of minutes between .Dq mark diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 881fe0b79c0..db8ef33f7f1 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syslogd.c,v 1.208 2016/07/06 19:29:13 millert Exp $ */ +/* $OpenBSD: syslogd.c,v 1.209 2016/07/12 09:47:25 bluhm Exp $ */ /* * Copyright (c) 1983, 1988, 1993, 1994 @@ -225,6 +225,8 @@ struct tls *server_ctx; struct tls_config *client_config, *server_config; const char *CAfile = "/etc/ssl/cert.pem"; /* file containing CA certificates */ int NoVerify = 0; /* do not verify TLS server x509 certificate */ +char *ClientCertfile = NULL; +char *ClientKeyfile = NULL; int tcpbuf_dropped = 0; /* count messages dropped from TCP or TLS */ #define CTL_READING_CMD 1 @@ -353,7 +355,8 @@ main(int argc, char *argv[]) int ch, i; int lockpipe[2] = { -1, -1}, pair[2], nullfd, fd; - while ((ch = getopt(argc, argv, "46a:C:dFf:hm:np:S:s:T:U:uV")) != -1) + while ((ch = getopt(argc, argv, "46a:C:c:dFf:hk:m:np:S:s:T:U:uV")) + != -1) switch (ch) { case '4': /* disable IPv6 */ Family = PF_INET; @@ -369,6 +372,9 @@ main(int argc, char *argv[]) case 'C': /* file containing CA certificates */ CAfile = optarg; break; + case 'c': /* file containing client certificate */ + ClientCertfile = optarg; + break; case 'd': /* debug */ Debug++; break; @@ -381,6 +387,9 @@ main(int argc, char *argv[]) case 'h': /* RFC 3164 hostnames */ IncludeHostname = 1; break; + case 'k': /* file containing client key */ + ClientKeyfile = optarg; + break; case 'm': /* mark interval */ MarkInterval = strtonum(optarg, 0, 365*24*60, &errstr); if (errstr) @@ -582,6 +591,31 @@ main(int argc, char *argv[]) free(p); close(fd); } + if (ClientCertfile && ClientKeyfile) { + uint8_t *cert, *key; + size_t certlen, keylen; + + cert = tls_load_file(ClientCertfile, &certlen, NULL); + if (cert == NULL) { + logerror("load client TLS cert failed"); + } else if (tls_config_set_cert_mem(client_config, cert, + certlen) == -1) { + logerror("set client TLS cert failed"); + } else { + logdebug("ClientCertfile %s\n", ClientCertfile); + } + key = tls_load_file(ClientKeyfile, &keylen, NULL); + if (key == NULL) { + logerror("load client TLS key failed"); + } else if (tls_config_set_key_mem(client_config, key, + keylen) == -1) { + logerror("set client TLS key failed"); + } else { + logdebug("ClientKeyfile %s\n", ClientKeyfile); + } + } else if (ClientCertfile || ClientKeyfile) { + logerrorx("options -c and -k must be used together"); + } tls_config_set_protocols(client_config, TLS_PROTOCOLS_ALL); if (tls_config_set_ciphers(client_config, "compat") != 0) logerror("tls set client ciphers"); @@ -1483,9 +1517,10 @@ usage(void) { (void)fprintf(stderr, - "usage: syslogd [-46dFhnuV] [-a path] [-C CAfile] [-f config_file]\n" - " [-m mark_interval] [-p log_socket] [-S listen_address]\n" - " [-s reporting_socket] [-T listen_address] [-U bind_address]\n"); + "usage: syslogd [-46dFhnuV] [-a path] [-C CAfile] [-c cert_file]\n" + "\t[-f config_file] [-k key_file] [-m mark_interval]\n" + "\t[-p log_socket] [-S listen_address] [-s reporting_socket]\n" + "\t[-T listen_address] [-U bind_address]\n"); exit(1); }