aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@esdenera.com>2015-07-16 21:06:14 +0200
committerReyk Floeter <reyk@esdenera.com>2015-07-16 21:06:14 +0200
commitc690aa7c2b56f7fb30f72222928b0f7563a1e7e1 (patch)
tree78a4b306da3389048c0948eb6155b50d0cfbc87e
parent5534dbfa66d3e3bf884fc09cd4e0ff296b6f7bdc (diff)
downloadhttpd-c690aa7c2b56f7fb30f72222928b0f7563a1e7e1.tar.gz
httpd-c690aa7c2b56f7fb30f72222928b0f7563a1e7e1.zip
sync with -current during c2k15
-rw-r--r--httpd/config.c150
-rw-r--r--httpd/httpd.conf.58
-rw-r--r--httpd/httpd.h19
-rw-r--r--httpd/parse.y6
-rw-r--r--httpd/patterns.713
-rw-r--r--httpd/patterns.c12
-rw-r--r--httpd/patterns.h8
-rw-r--r--httpd/server.c55
-rw-r--r--httpd/server_file.c38
-rw-r--r--httpd/server_http.c101
10 files changed, 313 insertions, 97 deletions
diff --git a/httpd/config.c b/httpd/config.c
index 7635c33..3c88990 100644
--- a/httpd/config.c
+++ b/httpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.37 2015/04/11 14:52:49 jsing Exp $ */
+/* $OpenBSD: config.c,v 1.39 2015/07/15 16:00:39 jsing Exp $ */
/*
* Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -193,14 +193,6 @@ config_setserver(struct httpd *env, struct server *srv)
iov[c].iov_base = srv->srv_conf.return_uri;
iov[c++].iov_len = srv->srv_conf.return_uri_len;
}
- if (srv->srv_conf.tls_cert_len != 0) {
- iov[c].iov_base = srv->srv_conf.tls_cert;
- iov[c++].iov_len = srv->srv_conf.tls_cert_len;
- }
- if (srv->srv_conf.tls_key_len != 0) {
- iov[c].iov_base = srv->srv_conf.tls_key;
- iov[c++].iov_len = srv->srv_conf.tls_key_len;
- }
if (id == PROC_SERVER &&
(srv->srv_conf.flags & SRVFLAG_LOCATION) == 0) {
@@ -220,6 +212,9 @@ config_setserver(struct httpd *env, struct server *srv)
return (-1);
}
}
+
+ /* Configure TLS if necessary. */
+ config_settls(env, srv);
} else {
if (proc_composev_imsg(ps, id, -1, IMSG_CFG_SERVER, -1,
iov, c) != 0) {
@@ -235,6 +230,72 @@ config_setserver(struct httpd *env, struct server *srv)
}
int
+config_settls(struct httpd *env, struct server *srv)
+{
+ struct privsep *ps = env->sc_ps;
+ struct tls_config tls;
+ struct iovec iov[2];
+ size_t c;
+
+ if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
+ return (0);
+
+ log_debug("%s: configuring TLS for %s", __func__, srv->srv_conf.name);
+
+ if (srv->srv_conf.tls_cert_len != 0) {
+ DPRINTF("%s: sending TLS cert \"%s[%u]\" to %s fd %d", __func__,
+ srv->srv_conf.name, srv->srv_conf.id,
+ ps->ps_title[PROC_SERVER], srv->srv_s);
+
+ memset(&tls, 0, sizeof(tls));
+ tls.id = srv->srv_conf.id;
+ tls.port = srv->srv_conf.port;
+ memcpy(&tls.ss, &srv->srv_conf.ss, sizeof(tls.ss));
+ tls.tls_cert_len = srv->srv_conf.tls_cert_len;
+
+ c = 0;
+ iov[c].iov_base = &tls;
+ iov[c++].iov_len = sizeof(tls);
+ iov[c].iov_base = srv->srv_conf.tls_cert;
+ iov[c++].iov_len = srv->srv_conf.tls_cert_len;
+
+ if (proc_composev_imsg(ps, PROC_SERVER, -1, IMSG_CFG_TLS, -1,
+ iov, c) != 0) {
+ log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+ "`%s'", __func__, srv->srv_conf.name);
+ return (-1);
+ }
+ }
+
+ if (srv->srv_conf.tls_key_len != 0) {
+ DPRINTF("%s: sending TLS key \"%s[%u]\" to %s fd %d", __func__,
+ srv->srv_conf.name, srv->srv_conf.id,
+ ps->ps_title[PROC_SERVER], srv->srv_s);
+
+ memset(&tls, 0, sizeof(tls));
+ tls.id = srv->srv_conf.id;
+ tls.port = srv->srv_conf.port;
+ memcpy(&tls.ss, &srv->srv_conf.ss, sizeof(tls.ss));
+ tls.tls_key_len = srv->srv_conf.tls_key_len;
+
+ c = 0;
+ iov[c].iov_base = &tls;
+ iov[c++].iov_len = sizeof(tls);
+ iov[c].iov_base = srv->srv_conf.tls_key;
+ iov[c++].iov_len = srv->srv_conf.tls_key_len;
+
+ if (proc_composev_imsg(ps, PROC_SERVER, -1, IMSG_CFG_TLS, -1,
+ iov, c) != 0) {
+ log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+ "`%s'", __func__, srv->srv_conf.name);
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+int
config_getserver_auth(struct httpd *env, struct server_config *srv_conf)
{
struct privsep *ps = env->sc_ps;
@@ -422,9 +483,7 @@ config_getserver(struct httpd *env, struct imsg *imsg)
/* Reset these variables to avoid free'ing invalid pointers */
serverconfig_reset(&srv_conf);
- if ((IMSG_DATA_SIZE(imsg) - s) <
- (srv_conf.tls_cert_len + srv_conf.tls_key_len +
- srv_conf.return_uri_len)) {
+ if ((IMSG_DATA_SIZE(imsg) - s) < (size_t)srv_conf.return_uri_len) {
log_debug("%s: invalid message length", __func__);
goto fail;
}
@@ -475,30 +534,69 @@ config_getserver(struct httpd *env, struct imsg *imsg)
goto fail;
s += srv->srv_conf.return_uri_len;
}
- if (srv->srv_conf.tls_cert_len != 0) {
+
+ return (0);
+
+ fail:
+ if (imsg->fd != -1)
+ close(imsg->fd);
+ if (srv != NULL)
+ serverconfig_free(&srv->srv_conf);
+ free(srv);
+
+ return (-1);
+}
+
+int
+config_gettls(struct httpd *env, struct imsg *imsg)
+{
+#ifdef DEBUG
+ struct privsep *ps = env->sc_ps;
+#endif
+ struct server *srv = NULL;
+ struct tls_config tls_conf;
+ u_int8_t *p = imsg->data;
+ size_t s;
+
+ IMSG_SIZE_CHECK(imsg, &tls_conf);
+ memcpy(&tls_conf, p, sizeof(tls_conf));
+ s = sizeof(tls_conf);
+
+ if ((IMSG_DATA_SIZE(imsg) - s) <
+ (tls_conf.tls_cert_len + tls_conf.tls_key_len)) {
+ log_debug("%s: invalid message length", __func__);
+ goto fail;
+ }
+
+ /* Find server with matching listening socket. */
+ if ((srv = server_byaddr((struct sockaddr *)
+ &tls_conf.ss, tls_conf.port)) == NULL) {
+ log_debug("%s: server not found", __func__);
+ goto fail;
+ }
+
+ DPRINTF("%s: %s %d TLS configuration \"%s[%u]\"", __func__,
+ ps->ps_title[privsep_process], ps->ps_instance,
+ srv->srv_conf.name, srv->srv_conf.id);
+
+ if (tls_conf.tls_cert_len != 0) {
+ srv->srv_conf.tls_cert_len = tls_conf.tls_cert_len;
if ((srv->srv_conf.tls_cert = get_data(p + s,
- srv->srv_conf.tls_cert_len)) == NULL)
+ tls_conf.tls_cert_len)) == NULL)
goto fail;
- s += srv->srv_conf.tls_cert_len;
+ s += tls_conf.tls_cert_len;
}
- if (srv->srv_conf.tls_key_len != 0) {
+ if (tls_conf.tls_key_len != 0) {
+ srv->srv_conf.tls_key_len = tls_conf.tls_key_len;
if ((srv->srv_conf.tls_key = get_data(p + s,
- srv->srv_conf.tls_key_len)) == NULL)
+ tls_conf.tls_key_len)) == NULL)
goto fail;
- s += srv->srv_conf.tls_key_len;
+ s += tls_conf.tls_key_len;
}
return (0);
fail:
- if (imsg->fd != -1)
- close(imsg->fd);
- if (srv != NULL) {
- free(srv->srv_conf.tls_cert);
- free(srv->srv_conf.tls_key);
- }
- free(srv);
-
return (-1);
}
diff --git a/httpd/httpd.conf.5 b/httpd/httpd.conf.5
index db73b8f..b3eaad8 100644
--- a/httpd/httpd.conf.5
+++ b/httpd/httpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: httpd.conf.5,v 1.63 2015/06/23 17:29:19 jmc Exp $
+.\" $OpenBSD: httpd.conf.5,v 1.64 2015/07/15 17:10:47 jsing Exp $
.\"
.\" Copyright (c) 2014, 2015 Reyk Floeter <reyk@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 23 2015 $
+.Dd $Mdocdate: July 15 2015 $
.Dt HTTPD.CONF 5
.Os
.Sh NAME
@@ -412,6 +412,8 @@ Specify the certificate to use for this server.
The
.Ar file
should contain a PEM encoded certificate.
+The default is
+.Pa /etc/ssl/server.crt .
.It Ic ciphers Ar string
Specify the TLS cipher string.
If not specified, the default value
@@ -438,6 +440,8 @@ should contain a PEM encoded private key and reside outside of the
.Xr chroot 2
root directory of
.Nm httpd .
+The default is
+.Pa /etc/ssl/private/server.key .
.It Ic protocols Ar string
Specify the TLS protocols to enable for this server.
If not specified, the value
diff --git a/httpd/httpd.h b/httpd/httpd.h
index 20d75a7..2cb7934 100644
--- a/httpd/httpd.h
+++ b/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.84 2015/06/23 15:23:14 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.88 2015/07/16 16:29:25 florian Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -34,6 +34,7 @@
#include <event.h>
#include <imsg.h>
#include <tls.h>
+#include <vis.h>
#include "patterns.h"
@@ -47,6 +48,7 @@
#define HTTPD_LOGROOT "/logs"
#define HTTPD_ACCESS_LOG "access.log"
#define HTTPD_ERROR_LOG "error.log"
+#define HTTPD_LOGVIS VIS_NL|VIS_TAB|VIS_CSTYLE
#define HTTPD_TLS_CERT "/etc/ssl/server.crt"
#define HTTPD_TLS_KEY "/etc/ssl/private/server.key"
#define HTTPD_TLS_CIPHERS "HIGH:!aNULL"
@@ -64,6 +66,8 @@
#define SERVER_MAXREQUESTBODY 1048576 /* 1M */
#define SERVER_BACKLOG 10
#define SERVER_OUTOF_FD_RETRIES 5
+#define SERVER_MAX_PREFETCH 256
+#define SERVER_MIN_PREFETCHED 32
#define MEDIATYPE_NAMEMAX 128 /* file name extension */
#define MEDIATYPE_TYPEMAX 64 /* length of type/subtype */
@@ -201,6 +205,7 @@ enum imsg_type {
IMSG_CTL_START,
IMSG_CTL_REOPEN,
IMSG_CFG_SERVER,
+ IMSG_CFG_TLS,
IMSG_CFG_MEDIA,
IMSG_CFG_AUTH,
IMSG_CFG_DONE,
@@ -442,6 +447,16 @@ struct server_config {
};
TAILQ_HEAD(serverhosts, server_config);
+struct tls_config {
+ u_int32_t id;
+
+ in_port_t port;
+ struct sockaddr_storage ss;
+
+ size_t tls_cert_len;
+ size_t tls_key_len;
+};
+
struct server {
TAILQ_ENTRY(server) srv_entry;
struct server_config srv_conf;
@@ -680,7 +695,9 @@ int config_setreset(struct httpd *, u_int);
int config_getreset(struct httpd *, struct imsg *);
int config_getcfg(struct httpd *, struct imsg *);
int config_setserver(struct httpd *, struct server *);
+int config_settls(struct httpd *, struct server *);
int config_getserver(struct httpd *, struct imsg *);
+int config_gettls(struct httpd *, struct imsg *);
int config_setmedia(struct httpd *, struct media_type *);
int config_getmedia(struct httpd *, struct imsg *);
int config_setauth(struct httpd *, struct auth *);
diff --git a/httpd/parse.y b/httpd/parse.y
index 1ba5cf3..0870819 100644
--- a/httpd/parse.y
+++ b/httpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.68 2015/06/23 15:23:14 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.70 2015/07/16 19:05:28 reyk Exp $ */
/*
* Copyright (c) 2007 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -408,7 +408,9 @@ serveroptsl : LISTEN ON STRING opttls port {
if (alias != NULL) {
/* IP-based; use name match flags from parent */
- alias->flags = srv->srv_conf.flags;
+ alias->flags &= ~SRVFLAG_SERVER_MATCH;
+ alias->flags |= srv->srv_conf.flags &
+ SRVFLAG_SERVER_MATCH;
TAILQ_INSERT_TAIL(&srv->srv_hosts,
alias, entry);
}
diff --git a/httpd/patterns.7 b/httpd/patterns.7
index 7c951db..a01ede5 100644
--- a/httpd/patterns.7
+++ b/httpd/patterns.7
@@ -1,4 +1,4 @@
-.\" $OpenBSD: patterns.7,v 1.2 2015/06/23 17:29:19 jmc Exp $
+.\" $OpenBSD: patterns.7,v 1.5 2015/06/30 19:01:05 jmc Exp $
.\"
.\" Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
.\" Copyright (C) 1994-2015 Lua.org, PUC-Rio.
@@ -23,9 +23,9 @@
.\" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
.\"
.\" Derived from section 6.4.1 in manual.html of Lua 5.3.1:
-.\" $Id: patterns.7,v 1.2 2015/06/23 17:29:19 jmc Exp $
+.\" $Id: patterns.7,v 1.5 2015/06/30 19:01:05 jmc Exp $
.\"
-.Dd $Mdocdate: June 23 2015 $
+.Dd $Mdocdate: June 30 2015 $
.Dt PATTERNS 7
.Os
.Sh NAME
@@ -268,7 +268,7 @@ For instance, if we apply the pattern
.Qq ()aa()
on the string
.Qq flaaap ,
-there will be two captures: 3 and 5.
+there will be two captures: 2 and 4.
.Sh SEE ALSO
.Xr fnmatch 3 ,
.Xr re_format 7 ,
@@ -302,3 +302,8 @@ It was turned into a native C API for
.Xr httpd 8
by
.An Reyk Floeter Aq Mt reyk@openbsd.org .
+.Sh CAVEATS
+A notable difference with the Lua implementation is the position in the string
+returned by captures.
+It follows the C-style indexing (position starting from 0)
+instead of Lua-style indexing (position starting from 1).
diff --git a/httpd/patterns.c b/httpd/patterns.c
index 3b2cbcc..27a813f 100644
--- a/httpd/patterns.c
+++ b/httpd/patterns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: patterns.c,v 1.2 2015/06/23 15:35:20 semarie Exp $ */
+/* $OpenBSD: patterns.c,v 1.3 2015/06/26 10:07:48 semarie Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -26,16 +26,16 @@
/*
* Derived from Lua 5.3.1:
- * $Id: patterns.c,v 1.2 2015/06/23 15:35:20 semarie Exp $
+ * $Id: patterns.c,v 1.3 2015/06/26 10:07:48 semarie Exp $
* Standard library for string operations and pattern-matching
*/
+#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <assert.h>
#include "patterns.h"
@@ -98,7 +98,7 @@ classend(struct match_state *ms, const char *p)
case L_ESC:
if (p == ms->p_end)
match_error(ms,
- "malformed pattern (ends with '%%')");
+ "malformed pattern (ends with '%')");
return p + 1;
case '[':
if (*p == '^')
diff --git a/httpd/patterns.h b/httpd/patterns.h
index e753849..74790b5 100644
--- a/httpd/patterns.h
+++ b/httpd/patterns.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: patterns.h,v 1.1 2015/06/23 15:23:14 reyk Exp $ */
+/* $OpenBSD: patterns.h,v 1.2 2015/06/26 17:26:29 semarie Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -16,12 +16,12 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
#ifndef PATTERNS_H
#define PATTERNS_H
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
#define MAXCAPTURES 32 /* Max no. of allowed captures in pattern */
#define MAXCCALLS 200 /* Max recusion depth in pattern matching */
#define MAXREPETITION 0xfffff /* Max for repetition items */
diff --git a/httpd/server.c b/httpd/server.c
index ca67a47..86d0dca 100644
--- a/httpd/server.c
+++ b/httpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.63 2015/04/23 16:59:28 florian Exp $ */
+/* $OpenBSD: server.c,v 1.70 2015/07/16 16:29:25 florian Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -41,6 +41,7 @@
#include <event.h>
#include <imsg.h>
#include <tls.h>
+#include <vis.h>
#include "httpd.h"
@@ -312,20 +313,31 @@ server_purge(struct server *srv)
void
serverconfig_free(struct server_config *srv_conf)
{
+ free(srv_conf->auth);
free(srv_conf->return_uri);
free(srv_conf->tls_cert_file);
- free(srv_conf->tls_cert);
free(srv_conf->tls_key_file);
- free(srv_conf->tls_key);
+
+ if (srv_conf->tls_cert != NULL) {
+ explicit_bzero(srv_conf->tls_cert, srv_conf->tls_cert_len);
+ free(srv_conf->tls_cert);
+ }
+
+ if (srv_conf->tls_key != NULL) {
+ explicit_bzero(srv_conf->tls_key, srv_conf->tls_key_len);
+ free(srv_conf->tls_key);
+ }
}
void
serverconfig_reset(struct server_config *srv_conf)
{
- srv_conf->tls_cert_file = srv_conf->tls_key_file = NULL;
- srv_conf->tls_cert = srv_conf->tls_key = NULL;
- srv_conf->return_uri = NULL;
srv_conf->auth = NULL;
+ srv_conf->return_uri = NULL;
+ srv_conf->tls_cert = NULL;
+ srv_conf->tls_cert_file = NULL;
+ srv_conf->tls_key = NULL;
+ srv_conf->tls_key_file = NULL;
}
struct server *
@@ -571,6 +583,11 @@ server_tls_readcb(int fd, short event, void *arg)
goto err;
}
+ if (len == 0) {
+ what |= EVBUFFER_EOF;
+ goto err;
+ }
+
if (evbuffer_add(bufev->input, rbuf, len) == -1) {
what |= EVBUFFER_ERROR;
goto err;
@@ -704,7 +721,7 @@ server_input(struct client *clt)
/* Adjust write watermark to the socket buffer output size */
bufferevent_setwatermark(clt->clt_bev, EV_WRITE,
- clt->clt_sndbufsiz, 0);
+ SERVER_MIN_PREFETCHED * clt->clt_sndbufsiz, 0);
/* Read at most amount of data that fits in one fcgi record. */
bufferevent_setwatermark(clt->clt_bev, EV_READ, 0, FCGI_CONTENT_SIZE);
@@ -729,6 +746,10 @@ server_write(struct bufferevent *bev, void *arg)
goto done;
bufferevent_enable(bev, EV_READ);
+
+ if (clt->clt_srvbev && !(clt->clt_srvbev->enabled & EV_READ))
+ bufferevent_enable(clt->clt_srvbev, EV_READ);
+
return;
done:
(*bev->errorcb)(bev, EVBUFFER_WRITE|EVBUFFER_EOF, bev->cbarg);
@@ -769,6 +790,11 @@ server_read(struct bufferevent *bev, void *arg)
goto fail;
if (clt->clt_done)
goto done;
+
+ if (EVBUFFER_LENGTH(EVBUFFER_OUTPUT(clt->clt_bev)) > (size_t)
+ SERVER_MAX_PREFETCH * clt->clt_sndbufsiz)
+ bufferevent_disable(bev, EV_READ);
+
return;
done:
(*bev->errorcb)(bev, EVBUFFER_READ|EVBUFFER_EOF, bev->cbarg);
@@ -919,7 +945,7 @@ server_accept(int fd, short event, void *arg)
close(s);
free(clt);
/*
- * the client struct was not completly set up, but still
+ * the client struct was not completely set up, but still
* counted as an inflight client. account for this.
*/
server_inflight_dec(NULL, __func__);
@@ -954,6 +980,7 @@ server_accept_tls(int fd, short event, void *arg)
} else if (ret != 0) {
log_warnx("%s: TLS accept failed - %s", __func__,
tls_error(srv->srv_tls_ctx));
+ server_close(clt, "TLS accept failed");
return;
}
@@ -1020,7 +1047,7 @@ server_log(struct client *clt, const char *msg)
{
char ibuf[HOST_NAME_MAX+1], obuf[HOST_NAME_MAX+1];
struct server_config *srv_conf = clt->clt_srv_conf;
- char *ptr = NULL;
+ char *ptr = NULL, *vmsg = NULL;
int debug_cmd = -1;
extern int verbose;
@@ -1050,13 +1077,14 @@ server_log(struct client *clt, const char *msg)
if (EVBUFFER_LENGTH(clt->clt_log) &&
evbuffer_add_printf(clt->clt_log, "\n") != -1)
ptr = evbuffer_readline(clt->clt_log);
+ (void)stravis(&vmsg, msg, HTTPD_LOGVIS);
server_sendlog(srv_conf, debug_cmd, "server %s, "
"client %d (%d active), %s:%u -> %s, "
"%s%s%s", srv_conf->name, clt->clt_id, server_clients,
- ibuf, ntohs(clt->clt_port), obuf, msg,
+ ibuf, ntohs(clt->clt_port), obuf, vmsg == NULL ? "" : vmsg,
ptr == NULL ? "" : ",", ptr == NULL ? "" : ptr);
- if (ptr != NULL)
- free(ptr);
+ free(vmsg);
+ free(ptr);
}
}
@@ -1118,6 +1146,9 @@ server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CFG_SERVER:
config_getserver(env, imsg);
break;
+ case IMSG_CFG_TLS:
+ config_gettls(env, imsg);
+ break;
case IMSG_CFG_DONE:
config_getcfg(env, imsg);
break;
diff --git a/httpd/server_file.c b/httpd/server_file.c
index 52e50ff..16b47d0 100644
--- a/httpd/server_file.c
+++ b/httpd/server_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_file.c,v 1.54 2015/05/05 11:10:13 florian Exp $ */
+/* $OpenBSD: server_file.c,v 1.55 2015/07/16 19:05:28 reyk Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -43,20 +43,20 @@ struct range {
off_t end;
};
-int server_file_access(struct httpd *, struct client *,
+int server_file_access(struct httpd *, struct client *,
char *, size_t);
-int server_file_request(struct httpd *, struct client *,
+int server_file_request(struct httpd *, struct client *,
char *, struct stat *);
-int server_partial_file_request(struct httpd *, struct client *,
+int server_partial_file_request(struct httpd *, struct client *,
char *, struct stat *, char *);
-int server_file_index(struct httpd *, struct client *,
+int server_file_index(struct httpd *, struct client *,
struct stat *);
int server_file_modified_since(struct http_descriptor *,
struct stat *);
-int server_file_method(struct client *);
-int parse_range_spec(char *, size_t, struct range *);
-struct range *parse_range(char *, size_t, int *);
-int buffer_add_range(int, struct evbuffer *, struct range *);
+int server_file_method(struct client *);
+int parse_range_spec(char *, size_t, struct range *);
+struct range *parse_range(char *, size_t, int *);
+int buffer_add_range(int, struct evbuffer *, struct range *);
int
server_file_access(struct httpd *env, struct client *clt,
@@ -296,9 +296,9 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
struct range *range;
struct evbuffer *evb = NULL;
size_t content_length;
- int code = 500, fd = -1, i, nranges, ret;
+ int code = 500, fd = -1, i, nranges, ret;
uint32_t boundary;
- char content_range[64];
+ char content_range[64];
const char *errstr = NULL;
/* Ignore range request for methods other than GET */
@@ -325,7 +325,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
if (nranges == 1) {
(void)snprintf(content_range, sizeof(content_range),
- "bytes %lld-%lld/%lld", range->start, range->end,
+ "bytes %lld-%lld/%lld", range->start, range->end,
st->st_size);
if (kv_add(&resp->http_headers, "Content-Range",
content_range) == NULL)
@@ -347,8 +347,8 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
content_length += i;
if ((i = evbuffer_add_printf(evb,
"Content-Type: %s/%s\r\n",
- media == NULL ? "application" : media->media_type,
- media == NULL ?
+ media == NULL ? "application" : media->media_type,
+ media == NULL ?
"octet-stream" : media->media_subtype)) == -1)
goto abort;
@@ -374,10 +374,10 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
/* prepare multipart/byteranges media type */
(void)strlcpy(multipart_media.media_type, "multipart",
- sizeof(multipart_media.media_type));
+ sizeof(multipart_media.media_type));
(void)snprintf(multipart_media.media_subtype,
- sizeof(multipart_media.media_subtype),
- "byteranges; boundary=%ud", boundary);
+ sizeof(multipart_media.media_subtype),
+ "byteranges; boundary=%ud", boundary);
media = &multipart_media;
}
@@ -656,7 +656,7 @@ struct range *
parse_range(char *str, size_t file_sz, int *nranges)
{
static struct range ranges[MAX_RANGES];
- int i = 0;
+ int i = 0;
char *p, *q;
/* Extract range unit */
@@ -692,7 +692,7 @@ parse_range(char *str, size_t file_sz, int *nranges)
int
parse_range_spec(char *str, size_t size, struct range *r)
{
- size_t start_str_len, end_str_len;
+ size_t start_str_len, end_str_len;
char *p, *start_str, *end_str;
const char *errstr;
diff --git a/httpd/server_http.c b/httpd/server_http.c
index 112bb00..9a6609e 100644
--- a/httpd/server_http.c
+++ b/httpd/server_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_http.c,v 1.84 2015/06/23 17:25:01 semarie Exp $ */
+/* $OpenBSD: server_http.c,v 1.89 2015/07/16 19:05:28 reyk Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -35,6 +35,7 @@
#include <resolv.h>
#include <event.h>
#include <ctype.h>
+#include <vis.h>
#include "httpd.h"
#include "http.h"
@@ -1007,7 +1008,7 @@ server_expand_http(struct client *clt, const char *val, char *buf,
return (NULL);
}
if (strstr(val, "$SERVER_NAME") != NULL) {
- if ((str = url_encode(srv_conf->name))
+ if ((str = url_encode(srv_conf->name))
== NULL)
return (NULL);
ret = expand_string(buf, len, "$SERVER_NAME", str);
@@ -1426,6 +1427,13 @@ server_log_http(struct client *clt, u_int code, size_t len)
struct tm *tm;
struct server_config *srv_conf;
struct http_descriptor *desc;
+ int ret = -1;
+ char *user = NULL;
+ char *path = NULL;
+ char *query = NULL;
+ char *version = NULL;
+ char *referrer_v = NULL;
+ char *agent_v = NULL;
if ((srv_conf = clt->clt_srv_conf) == NULL)
return (-1);
@@ -1454,18 +1462,34 @@ server_log_http(struct client *clt, u_int code, size_t len)
*/
switch (srv_conf->logformat) {
case LOG_FORMAT_COMMON:
- if (evbuffer_add_printf(clt->clt_log,
+ /* Use vis to encode input values from the header */
+ if (clt->clt_remote_user &&
+ stravis(&user, clt->clt_remote_user, HTTPD_LOGVIS) == -1)
+ goto done;
+ if (desc->http_version &&
+ stravis(&version, desc->http_version, HTTPD_LOGVIS) == -1)
+ goto done;
+
+ /* The following should be URL-encoded */
+ if (desc->http_path &&
+ (path = url_encode(desc->http_path)) == NULL)
+ goto done;
+ if (desc->http_query &&
+ (query = url_encode(desc->http_query)) == NULL)
+ goto done;
+
+ ret = evbuffer_add_printf(clt->clt_log,
"%s %s - %s [%s] \"%s %s%s%s%s%s\" %03d %zu\n",
srv_conf->name, ip, clt->clt_remote_user == NULL ? "-" :
- clt->clt_remote_user, tstamp,
+ user, tstamp,
server_httpmethod_byid(desc->http_method),
- desc->http_path == NULL ? "" : desc->http_path,
+ desc->http_path == NULL ? "" : path,
desc->http_query == NULL ? "" : "?",
- desc->http_query == NULL ? "" : desc->http_query,
+ desc->http_query == NULL ? "" : query,
desc->http_version == NULL ? "" : " ",
- desc->http_version == NULL ? "" : desc->http_version,
- code, len) == -1)
- return (-1);
+ desc->http_version == NULL ? "" : version,
+ code, len);
+
break;
case LOG_FORMAT_COMBINED:
@@ -1479,29 +1503,64 @@ server_log_http(struct client *clt, u_int code, size_t len)
agent->kv_value == NULL)
agent = NULL;
- if (evbuffer_add_printf(clt->clt_log,
+ /* Use vis to encode input values from the header */
+ if (clt->clt_remote_user &&
+ stravis(&user, clt->clt_remote_user, HTTPD_LOGVIS) == -1)
+ goto done;
+ if (desc->http_version &&
+ stravis(&version, desc->http_version, HTTPD_LOGVIS) == -1)
+ goto done;
+ if (agent &&
+ stravis(&agent_v, agent->kv_value, HTTPD_LOGVIS) == -1)
+ goto done;
+
+ /* The following should be URL-encoded */
+ if (desc->http_path &&
+ (path = url_encode(desc->http_path)) == NULL)
+ goto done;
+ if (desc->http_query &&
+ (query = url_encode(desc->http_query)) == NULL)
+ goto done;
+ if (referrer &&
+ (referrer_v = url_encode(referrer->kv_value)) == NULL)
+ goto done;
+
+ ret = evbuffer_add_printf(clt->clt_log,
"%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,
+ user, tstamp,
server_httpmethod_byid(desc->http_method),
- desc->http_path == NULL ? "" : desc->http_path,
+ desc->http_path == NULL ? "" : path,
desc->http_query == NULL ? "" : "?",
- desc->http_query == NULL ? "" : desc->http_query,
+ desc->http_query == NULL ? "" : query,
desc->http_version == NULL ? "" : " ",
- desc->http_version == NULL ? "" : desc->http_version,
+ desc->http_version == NULL ? "" : version,
code, len,
- referrer == NULL ? "" : referrer->kv_value,
- agent == NULL ? "" : agent->kv_value) == -1)
- return (-1);
+ referrer == NULL ? "" : referrer_v,
+ agent == NULL ? "" : agent_v);
+
break;
case LOG_FORMAT_CONNECTION:
- if (evbuffer_add_printf(clt->clt_log, " [%s]",
- desc->http_path == NULL ? "" : desc->http_path) == -1)
- return (-1);
+ /* URL-encode the path */
+ if (desc->http_path &&
+ (path = url_encode(desc->http_path)) == NULL)
+ goto done;
+
+ ret = evbuffer_add_printf(clt->clt_log, " [%s]",
+ desc->http_path == NULL ? "" : path);
+
break;
}
- return (0);
+done:
+ free(user);
+ free(path);
+ free(query);
+ free(version);
+ free(referrer_v);
+ free(agent_v);
+
+ return (ret);
}