From 683da8cfabc4850fdf7e1df7184299604cb00533 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Thu, 20 Nov 2014 14:40:40 +0100 Subject: sync --- Makefile | 6 ++-- http.h | 6 ++-- httpd.c | 50 ++++++++++++++++++++++++++++++-- httpd.conf.5 | 11 ++++++-- httpd.h | 13 +++++---- log.c | 3 +- logger.c | 9 ++++-- parse.y | 66 +++++++++++++++++++++++++++++++++---------- proc.c | 3 +- server.c | 91 ++++++++++++++++++++++++++++++++++------------------------- server_fcgi.c | 76 +++++++++++++++++++++++++++++++++++++++++++++---- server_file.c | 21 ++++++++------ server_http.c | 46 +++++++++++++++++++++--------- 13 files changed, 298 insertions(+), 103 deletions(-) diff --git a/Makefile b/Makefile index 63d50f4..441e02c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.25 2014/08/04 17:38:12 reyk Exp $ +# $OpenBSD: Makefile,v 1.26 2014/10/31 13:49:52 jsing Exp $ PROG= httpd SRCS= parse.y @@ -6,8 +6,8 @@ SRCS+= config.c control.c httpd.c log.c logger.c proc.c SRCS+= server.c server_http.c server_file.c server_fcgi.c MAN= httpd.8 httpd.conf.5 -LDADD= -levent -lressl -lssl -lcrypto -lutil -DPADD= ${LIBEVENT} ${LIBRESSL} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL} +LDADD= -levent -ltls -lssl -lcrypto -lutil +DPADD= ${LIBEVENT} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL} #DEBUG= -g -DDEBUG=3 CFLAGS+= -Wall -I${.CURDIR} CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes diff --git a/http.h b/http.h index 7e67a5c..c03c5d5 100644 --- a/http.h +++ b/http.h @@ -1,4 +1,4 @@ -/* $OpenBSD: http.h,v 1.8 2014/09/05 15:06:05 reyk Exp $ */ +/* $OpenBSD: http.h,v 1.9 2014/09/29 19:30:47 deraadt Exp $ */ /* * Copyright (c) 2012 - 2014 Reyk Floeter @@ -66,7 +66,7 @@ enum httpmethod { /* WebDAV Redirect Reference Resources, RFC 4437 */ HTTP_METHOD_MKREDIRECTREF, HTTP_METHOD_UPDATEREDIRECTREF, - + /* WebDAV Search, RFC 5323 */ HTTP_METHOD_SEARCH, @@ -108,7 +108,7 @@ struct http_method { { HTTP_METHOD_MERGE, "MERGE" }, \ { HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" }, \ { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" }, \ - { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" }, \ + { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" }, \ { HTTP_METHOD_ACL, "ACL" }, \ { HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" }, \ { HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" }, \ diff --git a/httpd.c b/httpd.c index 9284eb7..6579e6b 100644 --- a/httpd.c +++ b/httpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.c,v 1.21 2014/09/05 10:04:20 reyk Exp $ */ +/* $OpenBSD: httpd.c,v 1.24 2014/11/11 15:54:45 beck Exp $ */ /* * Copyright (c) 2014 Reyk Floeter @@ -231,6 +231,12 @@ main(int argc, char *argv[]) for (proc = 0; proc < nitems(procs); proc++) procs[proc].p_chroot = env->sc_chroot; + if (env->sc_logdir == NULL) { + if (asprintf(&env->sc_logdir, "%s%s", env->sc_chroot, + HTTPD_LOGROOT) == -1) + errx(1, "malloc failed"); + } + proc_init(ps, procs, nitems(procs)); setproctitle("parent"); @@ -535,6 +541,46 @@ canonicalize_host(const char *host, char *name, size_t len) return (NULL); } +const char * +url_decode(char *url) +{ + char *p, *q; + char hex[3]; + u_long x; + + hex[2] = '\0'; + p = q = url; + + while (*p != '\0') { + switch (*p) { + case '%': + /* Encoding character is followed by two hex chars */ + if (!(isxdigit(p[1]) && isxdigit(p[2]))) + return (NULL); + + hex[0] = p[1]; + hex[1] = p[2]; + + /* + * We don't have to validate "hex" because it is + * guaranteed to include two hex chars followed by nul. + */ + x = strtoul(hex, NULL, 16); + *q = (char)x; + p += 2; + break; + default: + *q = *p; + break; + } + p++; + q++; + } + *q = '\0'; + + return(url); +} + const char * canonicalize_path(const char *input, char *path, size_t len) { @@ -661,7 +707,7 @@ evbuffer_getline(struct evbuffer *evb) free(str); return (NULL); } - + str[i] = '\0'; if ((i + 1) < len) { diff --git a/httpd.conf.5 b/httpd.conf.5 index 6d267d6..b6177d3 100644 --- a/httpd.conf.5 +++ b/httpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: httpd.conf.5,v 1.34 2014/09/01 12:22:38 jmc Exp $ +.\" $OpenBSD: httpd.conf.5,v 1.36 2014/11/12 16:52:44 jmc Exp $ .\" .\" Copyright (c) 2014 Reyk Floeter .\" @@ -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: September 1 2014 $ +.Dd $Mdocdate: November 12 2014 $ .Dt HTTPD.CONF 5 .Os .Sh NAME @@ -103,6 +103,13 @@ directory. If not specified, it defaults to .Pa /var/www , the home directory of the www user. +.It Ic logdir Ar directory +Specifies the full path of the directory in which log files will be written. +If not specified, it defaults to +.Pa /logs +within the +.Xr chroot 2 +directory. .It Ic prefork Ar number Run the specified number of server processes. This increases the performance and prevents delays when connecting diff --git a/httpd.h b/httpd.h index 9ddf3c0..5e39fe1 100644 --- a/httpd.h +++ b/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.59 2014/09/10 15:39:57 reyk Exp $ */ +/* $OpenBSD: httpd.h,v 1.63 2014/11/11 15:54:45 beck Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -26,7 +26,7 @@ #include /* MAXHOSTNAMELEN */ #include #include -#include +#include #define CONF_FILE "/etc/httpd.conf" #define HTTPD_SOCKET "/var/run/httpd.sock" @@ -281,7 +281,7 @@ struct client { int clt_sndbufsiz; int clt_fd; - struct ressl *clt_ressl_ctx; + struct tls *clt_tls_ctx; struct bufferevent *clt_srvbev; off_t clt_toread; @@ -408,8 +408,8 @@ struct server { struct event srv_ev; struct event srv_evt; - struct ressl *srv_ressl_ctx; - struct ressl_config *srv_ressl_config; + struct tls *srv_tls_ctx; + struct tls_config *srv_tls_config; struct client_tree srv_clients; }; @@ -433,6 +433,7 @@ struct httpd { u_int16_t sc_id; int sc_paused; char *sc_chroot; + char *sc_logdir; struct serverlist *sc_servers; struct mediatypes *sc_mediatypes; @@ -543,6 +544,7 @@ int fcgi_add_stdin(struct client *, struct evbuffer *); void event_again(struct event *, int, short, void (*)(int, short, void *), struct timeval *, struct timeval *, void *); +const char *url_decode(char *); const char *canonicalize_host(const char *, char *, size_t); const char *canonicalize_path(const char *, char *, size_t); size_t path_info(char *); @@ -586,6 +588,7 @@ void log_warn(const char *, ...) __attribute__((__format__ (printf, 1, 2))); void log_warnx(const char *, ...) __attribute__((__format__ (printf, 1, 2))); void log_info(const char *, ...) __attribute__((__format__ (printf, 1, 2))); void log_debug(const char *, ...) __attribute__((__format__ (printf, 1, 2))); +void logit(int, const char *, ...) __attribute__((__format__ (printf, 2, 3))); void vlog(int, const char *, va_list) __attribute__((__format__ (printf, 2, 0))); __dead void fatal(const char *); __dead void fatalx(const char *); diff --git a/log.c b/log.c index c500d2e..dc06b16 100644 --- a/log.c +++ b/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.2 2014/08/04 11:09:25 reyk Exp $ */ +/* $OpenBSD: log.c,v 1.3 2014/10/25 03:23:49 lteo Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/logger.c b/logger.c index 665db75..9402695 100644 --- a/logger.c +++ b/logger.c @@ -1,4 +1,4 @@ -/* $OpenBSD: logger.c,v 1.5 2014/08/06 12:56:58 reyk Exp $ */ +/* $OpenBSD: logger.c,v 1.7 2014/11/11 15:54:45 beck Exp $ */ /* * Copyright (c) 2014 Reyk Floeter @@ -164,8 +164,8 @@ logger_open_priv(struct imsg *imsg) if ((size_t)snprintf(name, sizeof(name), "/%s", p) >= sizeof(name)) return (-1); - if ((len = (size_t)snprintf(path, sizeof(path), "%s%s", - env->sc_chroot, HTTPD_LOGROOT)) >= sizeof(path)) + if ((len = strlcpy(path, env->sc_logdir, sizeof(path))) + >= sizeof(path)) return (-1); p = path + len; @@ -194,6 +194,9 @@ 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); + /* disassociate */ srv_conf->logaccess = srv_conf->logerror = NULL; diff --git a/parse.y b/parse.y index 9ad7732..2124eb1 100644 --- a/parse.y +++ b/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.38 2014/09/05 10:04:20 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.42 2014/11/20 05:51:20 jsg Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter @@ -69,7 +69,9 @@ int popfile(void); int check_file_secrecy(int, const char *); int yyparse(void); int yylex(void); -int yyerror(const char *, ...); +int yyerror(const char *, ...) + __attribute__((__format__ (printf, 1, 2))) + __attribute__((__nonnull__ (1))); int kw_cmp(const void *, const void *); int lookup(char *); int lgetc(int); @@ -127,8 +129,8 @@ typedef struct { %token ACCESS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON %token COMBINED CONNECTION DIRECTORY ERR FCGI INDEX IP KEY LISTEN LOCATION -%token LOG MAXIMUM NO NODELAY ON PORT PREFORK REQUEST REQUESTS ROOT SACK -%token SERVER SOCKET SSL STYLE SYSLOG TCP TIMEOUT TYPES +%token LOG LOGDIR MAXIMUM NO NODELAY ON PORT PREFORK REQUEST REQUESTS ROOT +%token SACK SERVER SOCKET SSL STYLE SYSLOG TCP TIMEOUT TYPES %token ERROR INCLUDE %token STRING %token NUMBER @@ -181,7 +183,7 @@ main : PREFORK NUMBER { break; if ($2 <= 0 || $2 > SERVER_MAXPROC) { yyerror("invalid number of preforked " - "servers: %d", $2); + "servers: %lld", $2); YYERROR; } conf->sc_prefork_server = $2; @@ -189,6 +191,9 @@ main : PREFORK NUMBER { | CHROOT STRING { conf->sc_chroot = $2; } + | LOGDIR STRING { + conf->sc_logdir = $2; + } ; server : SERVER STRING { @@ -281,12 +286,18 @@ server : SERVER STRING { free(srv); YYERROR; } +<<<<<<< parse.y + + TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry); + +======= DPRINTF("adding server \"%s[%u]\"", srv->srv_conf.name, srv->srv_conf.id); TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry); +>>>>>>> 1.42 srv = NULL; srv_conf = NULL; } @@ -428,6 +439,26 @@ serveroptsl : LISTEN ON STRING optssl port { srv = s; srv_conf = &srv->srv_conf; SPLAY_INIT(&srv->srv_clients); +<<<<<<< parse.y + } '{' optnl serveropts_l '}' { + struct server *s = NULL; + + TAILQ_FOREACH(s, conf->sc_servers, srv_entry) { + if ((s->srv_conf.flags & SRVFLAG_LOCATION) && + s->srv_conf.id == srv_conf->id && + strcmp(s->srv_conf.location, + srv_conf->location) == 0) + break; + } + if (s != NULL) { + yyerror("location \"%s\" defined twice", + srv->srv_conf.location); + serverconfig_free(srv_conf); + free(srv); + YYABORT; + } + +======= } '{' optnl serveropts_l '}' { struct server *s = NULL; @@ -450,6 +481,7 @@ serveroptsl : LISTEN ON STRING optssl port { srv->srv_conf.location, srv->srv_conf.name, srv->srv_conf.id); +>>>>>>> 1.42 TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry); srv = parentsrv; @@ -658,7 +690,7 @@ tcpflags : SACK { srv_conf->tcpflags |= TCPFLAG_SACK; } } | BACKLOG NUMBER { if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) { - yyerror("invalid backlog: %d", $2); + yyerror("invalid backlog: %lld", $2); YYERROR; } srv_conf->tcpbacklog = $2; @@ -666,13 +698,13 @@ tcpflags : SACK { srv_conf->tcpflags |= TCPFLAG_SACK; } | SOCKET BUFFER NUMBER { srv_conf->tcpflags |= TCPFLAG_BUFSIZ; if ((srv_conf->tcpbufsiz = $3) < 0) { - yyerror("invalid socket buffer size: %d", $3); + yyerror("invalid socket buffer size: %lld", $3); YYERROR; } } | IP STRING NUMBER { if ($3 < 0) { - yyerror("invalid ttl: %d", $3); + yyerror("invalid ttl: %lld", $3); free($2); YYERROR; } @@ -768,7 +800,7 @@ port : PORT STRING { } | PORT NUMBER { if ($2 <= 0 || $2 >= (int)USHRT_MAX) { - yyerror("invalid port: %d", $2); + yyerror("invalid port: %lld", $2); YYERROR; } $$.val[0] = htons($2); @@ -779,7 +811,7 @@ port : PORT STRING { timeout : NUMBER { if ($1 < 0) { - yyerror("invalid timeout: %d\n", $1); + yyerror("invalid timeout: %lld", $1); YYERROR; } $$.tv_sec = $1; @@ -825,15 +857,15 @@ int yyerror(const char *fmt, ...) { va_list ap; - char *nfmt; + char *msg; file->errors++; va_start(ap, fmt); - if (asprintf(&nfmt, "%s:%d: %s", file->name, yylval.lineno, fmt) == -1) - fatalx("yyerror asprintf"); - vlog(LOG_CRIT, nfmt, ap); + if (vasprintf(&msg, fmt, ap) == -1) + fatalx("yyerror vasprintf"); va_end(ap); - free(nfmt); + logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg); + free(msg); return (0); } @@ -869,6 +901,7 @@ lookup(char *s) { "listen", LISTEN }, { "location", LOCATION }, { "log", LOG }, + { "logdir", LOGDIR }, { "max", MAXIMUM }, { "no", NO }, { "nodelay", NODELAY }, @@ -1060,6 +1093,9 @@ top: } else if (c == quotec) { *p = '\0'; break; + } else if (c == '\0') { + yyerror("syntax error"); + return (findeol()); } if (p + 1 >= buf + sizeof(buf) - 1) { yyerror("string too long"); diff --git a/proc.c b/proc.c index 25feff1..d0994f8 100644 --- a/proc.c +++ b/proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.c,v 1.4 2014/08/04 15:49:28 reyk Exp $ */ +/* $OpenBSD: proc.c,v 1.5 2014/10/25 03:23:49 lteo Exp $ */ /* * Copyright (c) 2010 - 2014 Reyk Floeter @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/server.c b/server.c index e756abb..4aa8307 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.42 2014/09/05 10:04:20 reyk Exp $ */ +/* $OpenBSD: server.c,v 1.46 2014/10/31 13:49:52 jsing Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -44,7 +43,7 @@ #include #include #include -#include +#include #include "httpd.h" @@ -175,33 +174,43 @@ server_ssl_init(struct server *srv) log_debug("%s: setting up SSL for %s", __func__, srv->srv_conf.name); - if (ressl_init() != 0) { - log_warn("%s: failed to initialise ressl", __func__); + if (tls_init() != 0) { + log_warn("%s: failed to initialise tls", __func__); return (-1); } - if ((srv->srv_ressl_config = ressl_config_new()) == NULL) { - log_warn("%s: failed to get ressl config", __func__); + if ((srv->srv_tls_config = tls_config_new()) == NULL) { + log_warn("%s: failed to get tls config", __func__); return (-1); } - if ((srv->srv_ressl_ctx = ressl_server()) == NULL) { - log_warn("%s: failed to get ressl server", __func__); + if ((srv->srv_tls_ctx = tls_server()) == NULL) { + log_warn("%s: failed to get tls server", __func__); return (-1); } - ressl_config_set_ciphers(srv->srv_ressl_config, - srv->srv_conf.ssl_ciphers); - ressl_config_set_cert_mem(srv->srv_ressl_config, - srv->srv_conf.ssl_cert, srv->srv_conf.ssl_cert_len); - ressl_config_set_key_mem(srv->srv_ressl_config, - srv->srv_conf.ssl_key, srv->srv_conf.ssl_key_len); + if (tls_config_set_ciphers(srv->srv_tls_config, + srv->srv_conf.ssl_ciphers) != 0) { + log_warn("%s: failed to set tls ciphers", __func__); + return (-1); + } + if (tls_config_set_cert_mem(srv->srv_tls_config, + srv->srv_conf.ssl_cert, srv->srv_conf.ssl_cert_len) != 0) { + log_warn("%s: failed to set tls cert", __func__); + return (-1); + } + if (tls_config_set_key_mem(srv->srv_tls_config, + srv->srv_conf.ssl_key, srv->srv_conf.ssl_key_len) != 0) { + log_warn("%s: failed to set tls key", __func__); + return (-1); + } - if (ressl_configure(srv->srv_ressl_ctx, srv->srv_ressl_config) != 0) { + if (tls_configure(srv->srv_tls_ctx, srv->srv_tls_config) != 0) { log_warn("%s: failed to configure SSL - %s", __func__, - ressl_error(srv->srv_ressl_ctx)); + tls_error(srv->srv_tls_ctx)); return (-1); } /* We're now done with the public/private key... */ + tls_config_clear_keys(srv->srv_tls_config); explicit_bzero(srv->srv_conf.ssl_cert, srv->srv_conf.ssl_cert_len); explicit_bzero(srv->srv_conf.ssl_key, srv->srv_conf.ssl_key_len); free(srv->srv_conf.ssl_cert); @@ -290,8 +299,8 @@ server_purge(struct server *srv) } } - ressl_config_free(srv->srv_ressl_config); - ressl_free(srv->srv_ressl_ctx); + tls_config_free(srv->srv_tls_config); + tls_free(srv->srv_tls_ctx); free(srv); } @@ -547,8 +556,8 @@ server_ssl_readcb(int fd, short event, void *arg) if (bufev->wm_read.high != 0) howmuch = MIN(sizeof(rbuf), bufev->wm_read.high); - ret = ressl_read(clt->clt_ressl_ctx, rbuf, howmuch, &len); - if (ret == RESSL_READ_AGAIN || ret == RESSL_WRITE_AGAIN) { + ret = tls_read(clt->clt_tls_ctx, rbuf, howmuch, &len); + if (ret == TLS_READ_AGAIN || ret == TLS_WRITE_AGAIN) { goto retry; } else if (ret != 0) { what |= EVBUFFER_ERROR; @@ -608,9 +617,9 @@ server_ssl_writecb(int fd, short event, void *arg) bcopy(EVBUFFER_DATA(bufev->output), clt->clt_buf, clt->clt_buflen); } - ret = ressl_write(clt->clt_ressl_ctx, clt->clt_buf, + ret = tls_write(clt->clt_tls_ctx, clt->clt_buf, clt->clt_buflen, &len); - if (ret == RESSL_READ_AGAIN || ret == RESSL_WRITE_AGAIN) { + if (ret == TLS_READ_AGAIN || ret == TLS_WRITE_AGAIN) { goto retry; } else if (ret != 0) { what |= EVBUFFER_ERROR; @@ -733,8 +742,8 @@ server_dump(struct client *clt, const void *buf, size_t len) * of non-blocking events etc. This is useful to print an * error message before gracefully closing the client. */ - if (clt->clt_ressl_ctx != NULL) - (void)ressl_write(clt->clt_ressl_ctx, buf, len, &outlen); + if (clt->clt_tls_ctx != NULL) + (void)tls_write(clt->clt_tls_ctx, buf, len, &outlen); else (void)write(clt->clt_s, buf, len); } @@ -771,6 +780,14 @@ server_error(struct bufferevent *bev, short error, void *arg) server_close(clt, "buffer event timeout"); return; } + if (error & EVBUFFER_ERROR) { + if (errno == EFBIG) { + bufferevent_enable(bev, EV_READ); + return; + } + server_close(clt, "buffer event error"); + return; + } if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) { bufferevent_disable(bev, EV_READ|EV_WRITE); @@ -786,11 +803,7 @@ server_error(struct bufferevent *bev, short error, void *arg) server_close(clt, "done"); return; } - if (error & EVBUFFER_ERROR && errno == EFBIG) { - bufferevent_enable(bev, EV_READ); - return; - } - server_close(clt, "buffer event error"); + server_close(clt, "unknown event error"); return; } @@ -921,22 +934,22 @@ server_accept_ssl(int fd, short event, void *arg) return; } - if (srv->srv_ressl_ctx == NULL) - fatalx("NULL ressl context"); + if (srv->srv_tls_ctx == NULL) + fatalx("NULL tls context"); - ret = ressl_accept_socket(srv->srv_ressl_ctx, &clt->clt_ressl_ctx, + ret = tls_accept_socket(srv->srv_tls_ctx, &clt->clt_tls_ctx, clt->clt_s); - if (ret == RESSL_READ_AGAIN) { + if (ret == TLS_READ_AGAIN) { event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_READ, server_accept_ssl, &clt->clt_tv_start, &srv->srv_conf.timeout, clt); - } else if (ret == RESSL_WRITE_AGAIN) { + } else if (ret == TLS_WRITE_AGAIN) { event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_WRITE, server_accept_ssl, &clt->clt_tv_start, &srv->srv_conf.timeout, clt); } else if (ret != 0) { log_warnx("%s: SSL accept failed - %s", __func__, - ressl_error(srv->srv_ressl_ctx)); + tls_error(srv->srv_tls_ctx)); return; } @@ -1071,9 +1084,9 @@ server_close(struct client *clt, const char *msg) if (clt->clt_s != -1) close(clt->clt_s); - if (clt->clt_ressl_ctx != NULL) - ressl_close(clt->clt_ressl_ctx); - ressl_free(clt->clt_ressl_ctx); + if (clt->clt_tls_ctx != NULL) + tls_close(clt->clt_tls_ctx); + tls_free(clt->clt_tls_ctx); server_inflight_dec(clt, __func__); diff --git a/server_fcgi.c b/server_fcgi.c index c51d4b5..17fdca9 100644 --- a/server_fcgi.c +++ b/server_fcgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_fcgi.c,v 1.38 2014/09/02 16:20:41 reyk Exp $ */ +/* $OpenBSD: server_fcgi.c,v 1.40 2014/10/25 03:23:49 lteo Exp $ */ /* * Copyright (c) 2014 Florian Obser @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -97,12 +96,24 @@ server_fcgi(struct httpd *env, struct client *clt) { struct server_fcgi_param param; struct server_config *srv_conf = clt->clt_srv_conf; +<<<<<<< server_fcgi.c struct http_descriptor *desc = clt->clt_descreq; + struct sockaddr_un sun; +======= + struct http_descriptor *desc = clt->clt_descreq; +>>>>>>> 1.40 struct fcgi_record_header *h; struct fcgi_begin_request_body *begin; +<<<<<<< server_fcgi.c + size_t len; + char hbuf[MAXHOSTNAMELEN]; + size_t scriptlen; + int pathlen; +======= char hbuf[MAXHOSTNAMELEN]; size_t scriptlen; int pathlen; +>>>>>>> 1.40 int fd = -1, ret; const char *errstr = NULL; char *str, *p, *script = NULL; @@ -129,7 +140,7 @@ server_fcgi(struct httpd *env, struct client *clt) } else { struct sockaddr_un sun; size_t len; - + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) goto fail; @@ -476,8 +487,8 @@ server_fcgi_read(struct bufferevent *bev, void *arg) EVBUFFER_DATA(clt->clt_srvevb); DPRINTF("%s: record header: version %d type %d id %d " "content len %d padding %d", __func__, - h->version, h->type, ntohs(h->id), - ntohs(h->content_len), h->padding_len); + h->version, h->type, ntohs(h->id), + ntohs(h->content_len), h->padding_len); clt->clt_fcgi_type = h->type; clt->clt_fcgi_toread = ntohs(h->content_len); clt->clt_fcgi_padding_len = h->padding_len; @@ -656,6 +667,60 @@ server_fcgi_writeheader(struct client *clt, struct kv *hdr, void *arg) int server_fcgi_writechunk(struct client *clt) { +<<<<<<< server_fcgi.c + struct evbuffer *evb = clt->clt_srvevb; + size_t len; + + if (clt->clt_fcgi_type == FCGI_END_REQUEST) { + len = 0; + } else + len = EVBUFFER_LENGTH(evb); + + /* If len is 0, make sure to write the end marker only once */ + if (len == 0 && clt->clt_fcgi_end++) + return (0); + + if (clt->clt_fcgi_chunked) { + if (server_bufferevent_printf(clt, "%zx\r\n", len) == -1 || + server_bufferevent_write_chunk(clt, evb, len) == -1 || + server_bufferevent_print(clt, "\r\n") == -1) + return (-1); + } else + return (server_bufferevent_write_buffer(clt, evb)); + + return (0); +} + +int +server_fcgi_getheaders(struct client *clt) +{ + struct http_descriptor *resp = clt->clt_descresp; + struct evbuffer *evb = clt->clt_srvevb; + int code = 200; + char *line, *key, *value; + const char *errstr; + + while ((line = evbuffer_getline(evb)) != NULL && *line != '\0') { + key = line; + + if ((value = strchr(key, ':')) == NULL) + break; + if (*value == ':') { + *value++ = '\0'; + value += strspn(value, " \t"); + } else { + *value++ = '\0'; + } + + if (strcasecmp("Status", key) == 0) { + value[strcspn(value, " \t")] = '\0'; + code = (int)strtonum(value, 100, 600, &errstr); + if (errstr != NULL || server_httperror_byid( + code) == NULL) + code = 200; + } else { + (void)kv_add(&resp->http_headers, key, value); +======= struct evbuffer *evb = clt->clt_srvevb; size_t len; @@ -710,6 +775,7 @@ server_fcgi_getheaders(struct client *clt) code = 200; } else { (void)kv_add(&resp->http_headers, key, value); +>>>>>>> 1.40 } free(line); } diff --git a/server_file.c b/server_file.c index e8a487e..3a71959 100644 --- a/server_file.c +++ b/server_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_file.c,v 1.35 2014/08/29 13:01:46 reyk Exp $ */ +/* $OpenBSD: server_file.c,v 1.39 2014/10/25 03:23:49 lteo Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -311,7 +310,7 @@ server_file_index(struct httpd *env, struct client *clt, struct stat *st) /* A CSS stylesheet allows minimal customization by the user */ style = "body { background-color: white; color: black; font-family: " - "sans-serif; }"; + "sans-serif; }\nhr { border: 0; border-bottom: 1px dashed; }\n"; /* Generate simple HTML index document */ if (evbuffer_add_printf(evb, "clt_done = 1; @@ -448,10 +455,6 @@ server_file_error(struct bufferevent *bev, short error, void *arg) server_close(clt, "done"); return; } - if (error & EVBUFFER_ERROR && errno == EFBIG) { - bufferevent_enable(bev, EV_READ); - return; - } - server_close(clt, "buffer event error"); + server_close(clt, "unknown event error"); return; } diff --git a/server_http.c b/server_http.c index 3735131..1953036 100644 --- a/server_http.c +++ b/server_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_http.c,v 1.50 2014/09/15 08:00:27 reyk Exp $ */ +/* $OpenBSD: server_http.c,v 1.54 2014/10/25 03:23:49 lteo Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -340,7 +339,7 @@ server_read_http(struct bufferevent *bev, void *arg) case HTTP_METHOD_MERGE: case HTTP_METHOD_BASELINE_CONTROL: case HTTP_METHOD_MKACTIVITY: - case HTTP_METHOD_ORDERPATCH: + case HTTP_METHOD_ORDERPATCH: case HTTP_METHOD_ACL: case HTTP_METHOD_MKREDIRECTREF: case HTTP_METHOD_UPDATEREDIRECTREF: @@ -554,7 +553,7 @@ void server_reset_http(struct client *clt) { struct server *srv = clt->clt_srv; - + server_httpdesc_free(clt->clt_descreq); server_httpdesc_free(clt->clt_descresp); clt->clt_headerlen = 0; @@ -689,9 +688,6 @@ server_abort_http(struct client *clt, u_int code, const char *msg) /* Do not send details of the Internal Server Error */ switch (code) { - case 500: - /* Do not send details of the Internal Server Error */ - break; case 301: case 302: if (asprintf(&extraheader, "Location: %s\r\n", msg) == -1) { @@ -700,13 +696,23 @@ server_abort_http(struct client *clt, u_int code, const char *msg) } break; default: - text = msg; +<<<<<<< server_http.c +======= + /* + * Do not send details of the error. Traditionally, + * web servers responsed with the request path on 40x + * errors which could be abused to inject JavaScript etc. + * Instead of sanitizing the path here, we just don't + * reprint it. + */ +>>>>>>> 1.54 break; } /* A CSS stylesheet allows minimal customization by the user */ style = "body { background-color: white; color: black; font-family: " - "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }"; + "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n" + "hr { border: 0; border-bottom: 1px dashed; }\n"; /* Generate simple HTTP+HTML error document */ if (asprintf(&httpmsg, "HTTP/1.0 %03d %s\r\n" @@ -724,15 +730,15 @@ server_abort_http(struct client *clt, u_int code, const char *msg) "\n" "\n" "\n" - "

%s

\n" + "

%03d %s

\n" "
%s
\n" - "
%s at %s port %d
\n" + "
\n
%s
\n" "\n" "\n", code, httperr, tmbuf, HTTPD_SERVERNAME, extraheader == NULL ? "" : extraheader, - code, httperr, style, httperr, text, - HTTPD_SERVERNAME, hbuf, ntohs(srv_conf->port)) == -1) + code, httperr, style, code, httperr, text, + HTTPD_SERVERNAME) == -1) goto done; /* Dump the message without checking for success */ @@ -752,14 +758,27 @@ server_abort_http(struct client *clt, u_int code, const char *msg) void server_close_http(struct client *clt) { +<<<<<<< server_http.c struct http_descriptor *desc; desc = clt->clt_descreq; server_httpdesc_free(desc); free(desc); clt->clt_descreq = NULL; +======= + struct http_descriptor *desc; +>>>>>>> 1.54 + +<<<<<<< server_http.c + desc = clt->clt_descresp; +======= + desc = clt->clt_descreq; + server_httpdesc_free(desc); + free(desc); + clt->clt_descreq = NULL; desc = clt->clt_descresp; +>>>>>>> 1.54 server_httpdesc_free(desc); free(desc); clt->clt_descresp = NULL; @@ -780,6 +799,7 @@ server_response(struct httpd *httpd, struct client *clt) /* Canonicalize the request path */ if (desc->http_path == NULL || + url_decode(desc->http_path) == NULL || canonicalize_path(desc->http_path, path, sizeof(path)) == NULL) goto fail; free(desc->http_path); -- cgit v1.2.3-54-g00ecf