Add support for TLS client certificates in syslogd. This allows a
authorbluhm <bluhm@openbsd.org>
Tue, 12 Jul 2016 09:47:25 +0000 (09:47 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 12 Jul 2016 09:47:25 +0000 (09:47 +0000)
remote server to verify that the log messages from our syslogd are
authentic.
From Kapetanakis Giannis; man page input jmc@; OK jung@ deraadt@

usr.sbin/syslogd/syslogd.8
usr.sbin/syslogd/syslogd.c

index cbd4cf7..0c09aa1 100644 (file)
@@ -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
index 881fe0b..db8ef33 100644 (file)
@@ -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);
 }