From 8a2934048ba934e50ecc1736d554036fc39f6752 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Tue, 10 Feb 2015 06:19:57 +0100 Subject: sync with -current, add auto-(e)dhe support, other fixes --- config.c | 4 ++-- httpd.c | 4 ++-- httpd.conf.5 | 12 +++++++++++- httpd.h | 14 +++++++++----- logger.c | 4 ++-- parse.y | 40 +++++++++++++++++++++++++++++++++++----- server.c | 58 +++++++++++++++++++++------------------------------------- server_file.c | 5 +++-- server_http.c | 26 ++++++++++++++------------ 9 files changed, 99 insertions(+), 68 deletions(-) diff --git a/config.c b/config.c index e3dd94f..f631214 100644 --- a/config.c +++ b/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.34 2015/02/07 01:23:12 reyk Exp $ */ +/* $OpenBSD: config.c,v 1.35 2015/02/07 23:56:02 reyk Exp $ */ /* * Copyright (c) 2011 - 2015 Reyk Floeter @@ -407,7 +407,7 @@ config_getserver(struct httpd *env, struct imsg *imsg) /* Reset these variables to avoid free'ing invalid pointers */ serverconfig_reset(&srv_conf); - if ((off_t)(IMSG_DATA_SIZE(imsg) - s) < + if ((IMSG_DATA_SIZE(imsg) - s) < (srv_conf.tls_cert_len + srv_conf.tls_key_len)) { log_debug("%s: invalid message length", __func__); goto fail; diff --git a/httpd.c b/httpd.c index 5ea455e..f640dc2 100644 --- a/httpd.c +++ b/httpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.c,v 1.31 2015/01/21 22:21:05 reyk Exp $ */ +/* $OpenBSD: httpd.c,v 1.32 2015/02/08 00:00:59 reyk Exp $ */ /* * Copyright (c) 2014 Reyk Floeter @@ -584,7 +584,7 @@ url_decode(char *url) } *q = '\0'; - return(url); + return (url); } const char * diff --git a/httpd.conf.5 b/httpd.conf.5 index d5afe6d..f93b57e 100644 --- a/httpd.conf.5 +++ b/httpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: httpd.conf.5,v 1.48 2015/02/07 01:23:12 reyk Exp $ +.\" $OpenBSD: httpd.conf.5,v 1.50 2015/02/07 08:12:30 jmc Exp $ .\" .\" Copyright (c) 2014, 2015 Reyk Floeter .\" @@ -349,6 +349,16 @@ will be used (strong crypto cipher suites without anonymous DH). See the CIPHERS section of .Xr openssl 1 for information about SSL/TLS cipher suites and preference lists. +.It Ic dhe Ar params +Specify the DHE parameters to use for DHE cipher suites. +Valid parameter values are none, legacy and auto. +For legacy a fixed key length of 1024 bits is used, whereas for auto the key +length is determined automatically. +The default is none, which disables DHE cipher suites. +.It Ic ecdhe Ar curve +Specify the ECDHE curve to use for ECDHE cipher suites. +Valid parameter values are none, auto and the short name of any known curve. +The default is auto. .It Ic key Ar file Specify the private key to use for this server. The diff --git a/httpd.h b/httpd.h index d2f6469..98096c9 100644 --- a/httpd.h +++ b/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.75 2015/02/07 01:23:12 reyk Exp $ */ +/* $OpenBSD: httpd.h,v 1.77 2015/02/07 23:56:02 reyk Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter @@ -48,6 +48,8 @@ #define HTTPD_TLS_CERT "/etc/ssl/server.crt" #define HTTPD_TLS_KEY "/etc/ssl/private/server.key" #define HTTPD_TLS_CIPHERS "HIGH:!aNULL" +#define HTTPD_TLS_DHE_PARAMS "none" +#define HTTPD_TLS_ECDHE_CURVE "auto" #define FD_RESERVE 5 #define SERVER_MAX_CLIENTS 1024 @@ -399,12 +401,14 @@ struct server_config { u_int32_t maxrequests; size_t maxrequestbody; - char *tls_cert; - off_t tls_cert_len; + u_int8_t *tls_cert; + size_t tls_cert_len; char *tls_cert_file; char tls_ciphers[NAME_MAX]; - char *tls_key; - off_t tls_key_len; + char tls_dhe_params[NAME_MAX]; + char tls_ecdhe_curve[NAME_MAX]; + u_int8_t *tls_key; + size_t tls_key_len; char *tls_key_file; u_int32_t flags; diff --git a/logger.c b/logger.c index c7a9bc3..b4e4404 100644 --- a/logger.c +++ b/logger.c @@ -1,4 +1,4 @@ -/* $OpenBSD: logger.c,v 1.10 2015/01/21 22:21:05 reyk Exp $ */ +/* $OpenBSD: logger.c,v 1.11 2015/02/08 00:00:59 reyk Exp $ */ /* * Copyright (c) 2014 Reyk Floeter @@ -194,7 +194,7 @@ logger_open(struct server *srv, struct server_config *srv_conf, void *arg) struct log_file *log, *logfile = NULL, *errfile = NULL; if (srv_conf->flags & SRVFLAG_SYSLOG) - return(0); + return (0); /* disassociate */ srv_conf->logaccess = srv_conf->logerror = NULL; diff --git a/parse.y b/parse.y index daf61c2..51f7d98 100644 --- a/parse.y +++ b/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.61 2015/02/07 01:23:12 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.64 2015/02/08 04:50:32 reyk Exp $ */ /* * Copyright (c) 2007 - 2015 Reyk Floeter @@ -130,9 +130,9 @@ typedef struct { %} %token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON -%token COMBINED CONNECTION DIRECTORY ERR FCGI INDEX IP KEY LISTEN LOCATION -%token LOG LOGDIR MAXIMUM NO NODELAY ON PORT PREFORK REQUEST REQUESTS ROOT -%token SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT TLS TYPES +%token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LISTEN +%token LOCATION LOG LOGDIR MAXIMUM NO NODELAY ON PORT PREFORK REQUEST REQUESTS +%token ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TIMEOUT TLS TYPES %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS %token STRING %token NUMBER @@ -242,8 +242,15 @@ server : SERVER STRING { if ((s->srv_conf.tls_key_file = strdup(HTTPD_TLS_KEY)) == NULL) fatal("out of memory"); - strlcpy(s->srv_conf.tls_ciphers, HTTPD_TLS_CIPHERS, + strlcpy(s->srv_conf.tls_ciphers, + HTTPD_TLS_CIPHERS, sizeof(s->srv_conf.tls_ciphers)); + strlcpy(s->srv_conf.tls_dhe_params, + HTTPD_TLS_DHE_PARAMS, + sizeof(s->srv_conf.tls_dhe_params)); + strlcpy(s->srv_conf.tls_ecdhe_curve, + HTTPD_TLS_ECDHE_CURVE, + sizeof(s->srv_conf.tls_ecdhe_curve)); if (last_server_id == INT_MAX) { yyerror("too many servers defined"); @@ -616,6 +623,26 @@ tlsopts : CERTIFICATE STRING { } free($2); } + | DHE STRING { + if (strlcpy(srv_conf->tls_dhe_params, $2, + sizeof(srv_conf->tls_dhe_params)) >= + sizeof(srv_conf->tls_dhe_params)) { + yyerror("dhe too long"); + free($2); + YYERROR; + } + free($2); + } + | ECDHE STRING { + if (strlcpy(srv_conf->tls_ecdhe_curve, $2, + sizeof(srv_conf->tls_ecdhe_curve)) >= + sizeof(srv_conf->tls_ecdhe_curve)) { + yyerror("ecdhe too long"); + free($2); + YYERROR; + } + free($2); + } ; root : ROOT rootflags @@ -1049,8 +1076,10 @@ lookup(char *s) { "combined", COMBINED }, { "common", COMMON }, { "connection", CONNECTION }, + { "dhe", DHE }, { "directory", DIRECTORY }, { "drop", DROP }, + { "ecdhe", ECDHE }, { "error", ERR }, { "fastcgi", FCGI }, { "include", INCLUDE }, @@ -1665,6 +1694,7 @@ host_dns(const char *s, struct addresslist *al, int max, memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; /* DUMMY */ + hints.ai_flags = AI_ADDRCONFIG; error = getaddrinfo(s, NULL, &hints, &res0); if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) return (0); diff --git a/server.c b/server.c index 46f2e5c..6e63120 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.55 2015/02/07 01:23:12 reyk Exp $ */ +/* $OpenBSD: server.c,v 1.57 2015/02/07 23:56:02 reyk Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter @@ -130,50 +130,23 @@ server_privinit(struct server *srv) return (0); } -static char * -server_load_file(const char *filename, off_t *len) -{ - struct stat st; - off_t size; - char *buf = NULL; - int fd; - - if ((fd = open(filename, O_RDONLY)) == -1) - return (NULL); - if (fstat(fd, &st) != 0) - goto fail; - size = st.st_size; - if ((buf = calloc(1, size + 1)) == NULL) - goto fail; - if (read(fd, buf, size) != size) - goto fail; - - close(fd); - - *len = size; - return (buf); - - fail: - free(buf); - close(fd); - - return (NULL); -} - int server_tls_load_keypair(struct server *srv) { if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0) return (0); - if ((srv->srv_conf.tls_cert = server_load_file( - srv->srv_conf.tls_cert_file, &srv->srv_conf.tls_cert_len)) == NULL) + if ((srv->srv_conf.tls_cert = tls_load_file( + srv->srv_conf.tls_cert_file, &srv->srv_conf.tls_cert_len, + NULL)) == NULL) return (-1); log_debug("%s: using certificate %s", __func__, srv->srv_conf.tls_cert_file); - if ((srv->srv_conf.tls_key = server_load_file( - srv->srv_conf.tls_key_file, &srv->srv_conf.tls_key_len)) == NULL) + /* XXX allow to specify password for encrypted key */ + if ((srv->srv_conf.tls_key = tls_load_file( + srv->srv_conf.tls_key_file, &srv->srv_conf.tls_key_len, + NULL)) == NULL) return (-1); log_debug("%s: using private key %s", __func__, srv->srv_conf.tls_key_file); @@ -207,6 +180,17 @@ server_tls_init(struct server *srv) log_warn("%s: failed to set tls ciphers", __func__); return (-1); } + if (tls_config_set_dheparams(srv->srv_tls_config, + srv->srv_conf.tls_dhe_params) != 0) { + log_warn("%s: failed to set tls dhe params", __func__); + return (-1); + } + if (tls_config_set_ecdhecurve(srv->srv_tls_config, + srv->srv_conf.tls_ecdhe_curve) != 0) { + log_warn("%s: failed to set tls ecdhe curve", __func__); + return (-1); + } + if (tls_config_set_cert_mem(srv->srv_tls_config, srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len) != 0) { log_warn("%s: failed to set tls cert", __func__); @@ -334,8 +318,8 @@ serverconfig_free(struct server_config *srv_conf) void serverconfig_reset(struct server_config *srv_conf) { - srv_conf->tls_cert_file = srv_conf->tls_cert = - srv_conf->tls_key_file = srv_conf->tls_key = NULL; + srv_conf->tls_cert_file = srv_conf->tls_key_file = NULL; + srv_conf->tls_cert = srv_conf->tls_key = NULL; srv_conf->auth = NULL; } diff --git a/server_file.c b/server_file.c index 2add01e..b24f0c0 100644 --- a/server_file.c +++ b/server_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_file.c,v 1.48 2015/01/21 22:21:05 reyk Exp $ */ +/* $OpenBSD: server_file.c,v 1.49 2015/02/08 00:00:59 reyk Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter @@ -349,7 +349,8 @@ server_file_index(struct httpd *env, struct client *clt, struct stat *st) if (evbuffer_add_printf(evb, "%s%*s%s%20llu\n", dp->d_name, dp->d_name, - MAXIMUM(namewidth, 0), " ", tmstr, st->st_size) == -1) + MAXIMUM(namewidth, 0), " ", + tmstr, st->st_size) == -1) skip = 1; } free(dp); diff --git a/server_http.c b/server_http.c index d5acb05..d4d3c97 100644 --- a/server_http.c +++ b/server_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_http.c,v 1.72 2015/02/07 01:23:12 reyk Exp $ */ +/* $OpenBSD: server_http.c,v 1.74 2015/02/08 00:00:59 reyk Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter @@ -126,15 +126,16 @@ server_httpdesc_free(struct http_descriptor *desc) int server_http_authenticate(struct server_config *srv_conf, struct client *clt) { - FILE *fp = NULL; - struct http_descriptor *desc = clt->clt_descreq; - struct auth *auth = srv_conf->auth; - struct kv *ba, key; - size_t linesize = 0; - ssize_t linelen; - int ret = -1; - char *line = NULL, decoded[1024]; - char *clt_user = NULL, *clt_pass = NULL, *user = NULL, *pass = NULL; + char decoded[1024]; + FILE *fp = NULL; + struct http_descriptor *desc = clt->clt_descreq; + struct auth *auth = srv_conf->auth; + struct kv *ba, key; + size_t linesize = 0; + ssize_t linelen; + int ret = -1; + char *line = NULL, *user = NULL, *pass = NULL; + char *clt_user = NULL, *clt_pass = NULL; memset(decoded, 0, sizeof(decoded)); key.kv_key = "Authorization"; @@ -146,7 +147,7 @@ server_http_authenticate(struct server_config *srv_conf, struct client *clt) if (strncmp(ba->kv_value, "Basic ", strlen("Basic ")) != 0) goto done; - if (b64_pton(strchr(ba->kv_value, ' ') + 1, decoded, + if (b64_pton(strchr(ba->kv_value, ' ') + 1, (u_int8_t *)decoded, sizeof(decoded)) <= 0) goto done; @@ -1293,7 +1294,8 @@ server_log_http(struct client *clt, u_int code, size_t len) agent = NULL; if (evbuffer_add_printf(clt->clt_log, - "%s %s - %s [%s] \"%s %s%s%s%s%s\" %03d %zu \"%s\" \"%s\"\n", + "%s %s - %s [%s] \"%s %s%s%s%s%s\"" + " %03d %zu \"%s\" \"%s\"\n", srv_conf->name, ip, clt->clt_remote_user == NULL ? "-" : clt->clt_remote_user, tstamp, server_httpmethod_byid(desc->http_method), -- cgit v1.2.3-54-g00ecf