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);
}