On 23/06/16 18:14, Kapetanakis Giannis wrote:
Hi,

Following http://marc.info/?l=openbsd-tech&m=142136923124184&w=2 which added TLS client support in syslogd and since now libtls supports client certificates, this patch adds client's certificate support in syslogd for mutual authentication to a remote syslog server.

It is based on code from netcat.c

tested on -current logging to a a remote syslog-ng server using syslog driver requiring trusted certificates from it's peers.

It adds two switches:
 -c client_cert_file
 -k client_key_file

Minor modification in CAfile setup as well to match the netcat code.

It is missing manual page change for the two switches. I will fix this if ok.

comments?

Giannis


slightly improved version which handles CAfile if missing (like previous behavior).
Changed usage and removed unnecessary checks of CAfile.

Index: syslogd.c
===================================================================
RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.205
diff -u -p -r1.205 syslogd.c
--- syslogd.c   2 Apr 2016 19:55:10 -0000       1.205
+++ syslogd.c   23 Jun 2016 16:49:58 -0000
@@ -63,6 +63,7 @@
 #define DEFUPRI                (LOG_USER|LOG_NOTICE)
 #define DEFSPRI                (LOG_KERN|LOG_CRIT)
 #define TIMERINTVL     30              /* interval for checking flush, mark */
+#define DEFAULT_CA_FILE "/etc/ssl/cert.pem"
#include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -223,8 +224,16 @@ char       *path_ctlsock = NULL;   /* Path to co
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 */
+int    NoVerify = 0;           /* verify TLS server x509 certificate */
+char   *CAfile = DEFAULT_CA_FILE; /* file containing CA certificates */
+char   *PubCertfile = NULL; /* file containing public certificate */
+char   *PrivKeyfile = NULL; /* file containing private key */
+uint8_t        *cacert;
+size_t cacertlen;
+uint8_t        *privkey;
+size_t privkeylen;
+uint8_t        *pubcert;
+size_t pubcertlen;
 int    tcpbuf_dropped = 0;     /* count messages dropped from TCP or TLS */
#define CTL_READING_CMD 1
@@ -353,7 +362,7 @@ 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 +378,9 @@ main(int argc, char *argv[])
                case 'C':               /* file containing CA certificates */
                        CAfile = optarg;
                        break;
+               case 'c':               /* file containing public certificate */
+                       PubCertfile = optarg;
+                       break;
                case 'd':               /* debug */
                        Debug++;
                        break;
@@ -381,6 +393,9 @@ main(int argc, char *argv[])
                case 'h':               /* RFC 3164 hostnames */
                        IncludeHostname = 1;
                        break;
+               case 'k':               /* file containing private key */
+                       PrivKeyfile = optarg;
+                       break;
                case 'm':               /* mark interval */
                        MarkInterval = strtonum(optarg, 0, 365*24*60, &errstr);
                        if (errstr)
@@ -553,34 +568,33 @@ main(int argc, char *argv[])
                        tls_config_insecure_noverifycert(client_config);
                        tls_config_insecure_noverifyname(client_config);
                } else {
-                       struct stat sb;
                        int fail = 1;
- fd = -1;
-                       p = NULL;
-                       if ((fd = open(CAfile, O_RDONLY)) == -1) {
-                               logerror("open CAfile");
-                       } else if (fstat(fd, &sb) == -1) {
-                               logerror("fstat CAfile");
-                       } else if (sb.st_size > 50*1024*1024) {
-                               logerrorx("CAfile larger than 50MB");
-                       } else if ((p = calloc(sb.st_size, 1)) == NULL) {
-                               logerror("calloc CAfile");
-                       } else if (read(fd, p, sb.st_size) != sb.st_size) {
-                               logerror("read CAfile");
-                       } else if (tls_config_set_ca_mem(client_config, p,
-                           sb.st_size) == -1) {
-                               logerrorx("tls_config_set_ca_mem");
-                       } else {
+                       if ((cacert = tls_load_file(CAfile, &cacertlen, NULL)) 
== NULL)
+                               logerror("load CAfile");
+                       if (tls_config_set_ca_mem(client_config, cacert, 
cacertlen) == -1)
+                               logerror("set CAfile");
+                       else {
                                fail = 0;
-                               logdebug("CAfile %s, size %lld\n",
-                                   CAfile, sb.st_size);
+                               logdebug("CAfile %s\n", CAfile);
                        }
                        /* avoid reading default certs in chroot */
                        if (fail)
                                tls_config_set_ca_mem(client_config, "", 0);
-                       free(p);
-                       close(fd);
+               }
+               if (PubCertfile && PrivKeyfile) {
+                       if ((pubcert = tls_load_file(PubCertfile, &pubcertlen, 
NULL)) == NULL)
+                               errx(1, "unable to load TLS certificate file 
%s", PubCertfile);
+                       if (tls_config_set_cert_mem(client_config, pubcert, 
pubcertlen) == -1)
+                               errx(1, "unable to set TLS certificate file 
%s", PubCertfile);
+                       else
+                               logdebug("TLS certificate %s\n", PubCertfile);
+                       if ((privkey = tls_load_file(PrivKeyfile, &privkeylen, 
NULL)) == NULL)
+                               errx(1, "unable to load TLS key file %s", 
PrivKeyfile);
+                       if (tls_config_set_key_mem(client_config, privkey, 
privkeylen) == -1)
+                               errx(1, "unable to set TLS key file %s", 
PrivKeyfile);
+                       else
+                               logdebug("TLS key %s\n", PrivKeyfile);
                }
                tls_config_set_protocols(client_config, TLS_PROTOCOLS_ALL);
                if (tls_config_set_ciphers(client_config, "compat") != 0)
@@ -1483,9 +1497,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 certfile] [-f 
config_file]\n"
+           "               [-k keyfile] [-m mark_interval] [-p log_socket]\n"
+           "               [-S listen_address] [-s reporting_socket] [-T 
listen_address]\n"
+           "               [-U bind_address]\n");
        exit(1);
 }

Reply via email to