-/* $OpenBSD: config.c,v 1.19 2014/08/05 18:01:10 reyk Exp $ */
+/* $OpenBSD: config.c,v 1.20 2014/08/06 02:04:42 jsing Exp $ */
/*
* Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org>
c = 0;
iov[c].iov_base = &s;
iov[c++].iov_len = sizeof(s);
+ if (srv->srv_conf.ssl_cert_len != 0) {
+ iov[c].iov_base = srv->srv_conf.ssl_cert;
+ iov[c++].iov_len = srv->srv_conf.ssl_cert_len;
+ }
+ if (srv->srv_conf.ssl_key_len != 0) {
+ iov[c].iov_base = srv->srv_conf.ssl_key;
+ iov[c++].iov_len = srv->srv_conf.ssl_key_len;
+ }
if (id == PROC_SERVER &&
(srv->srv_conf.flags & SRVFLAG_LOCATION) == 0) {
#ifdef DEBUG
struct privsep *ps = env->sc_ps;
#endif
- struct server *srv;
+ struct server *srv = NULL;
struct server_config srv_conf;
u_int8_t *p = imsg->data;
size_t s;
memcpy(&srv_conf, p, sizeof(srv_conf));
s = sizeof(srv_conf);
+ if ((u_int)(IMSG_DATA_SIZE(imsg) - s) <
+ (srv_conf.ssl_cert_len + srv_conf.ssl_key_len)) {
+ log_debug("%s: invalid message length", __func__);
+ goto fail;
+ }
+
/* Check if server with matching listening socket already exists */
if ((srv = server_byaddr((struct sockaddr *)
&srv_conf.ss, srv_conf.port)) != NULL) {
srv->srv_conf.name,
printb_flags(srv->srv_conf.flags, SRVFLAG_BITS));
+ if (srv->srv_conf.ssl_cert_len != 0) {
+ if ((srv->srv_conf.ssl_cert = get_data(p + s,
+ srv->srv_conf.ssl_cert_len)) == NULL)
+ goto fail;
+ s += srv->srv_conf.ssl_cert_len;
+ }
+ if (srv->srv_conf.ssl_key_len != 0) {
+ if ((srv->srv_conf.ssl_key = get_data(p + s,
+ srv->srv_conf.ssl_key_len)) == NULL)
+ goto fail;
+ s += srv->srv_conf.ssl_key_len;
+ }
+
return (0);
+
+ fail:
+ free(srv->srv_conf.ssl_cert);
+ free(srv->srv_conf.ssl_key);
+ free(srv);
+
+ return (-1);
}
int
-.\" $OpenBSD: httpd.8,v 1.41 2014/08/04 18:12:15 reyk Exp $
+.\" $OpenBSD: httpd.8,v 1.42 2014/08/06 02:04:42 jsing Exp $
.\"
.\" Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 4 2014 $
+.Dd $Mdocdate: August 6 2014 $
.Dt HTTPD 8
.Os
.Sh NAME
.Ux Ns -domain
socket used for communication with
.Nm .
-.It /var/www/conf/server.key
-Default SSL/TLS server key.
-.It /var/www/conf/server.crt
+.It /etc/ssl/server.crt
Default SSL/TLS server certificate.
+.It /etc/ssl/private/server.key
+Default SSL/TLS server key.
.It /var/www/logs/access.log
Default access log file.
.It /var/www/logs/error.log
-/* $OpenBSD: httpd.h,v 1.46 2014/08/05 18:01:10 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.47 2014/08/06 02:04:42 jsing Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
#define HTTPD_LOGROOT "/logs"
#define HTTPD_ACCESS_LOG "access.log"
#define HTTPD_ERROR_LOG "error.log"
-#define HTTPD_SSL_KEY "/conf/server.key"
-#define HTTPD_SSL_CERT "/conf/server.crt"
+#define HTTPD_SSL_KEY "/etc/ssl/private/server.key"
+#define HTTPD_SSL_CERT "/etc/ssl/server.crt"
#define FD_RESERVE 5
#define SERVER_MAX_CLIENTS 1024
struct timeval timeout;
u_int32_t maxrequests;
+ char *ssl_cert;
+ off_t ssl_cert_len;
+ char *ssl_cert_file;
+ char *ssl_key;
+ off_t ssl_key_len;
+ char *ssl_key_file;
+
u_int16_t flags;
u_int8_t tcpflags;
int tcpbufsiz;
/* server.c */
pid_t server(struct privsep *, struct privsep_proc *);
+int server_ssl_load_keypair(struct server *);
int server_privinit(struct server *);
void server_purge(struct server *);
int server_socket_af(struct sockaddr_storage *, in_port_t);
-/* $OpenBSD: parse.y,v 1.28 2014/08/05 18:01:10 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.29 2014/08/06 02:04:42 jsing Exp $ */
/*
* Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
s->srv_conf.maxrequests = SERVER_MAXREQUESTS;
s->srv_conf.flags |= SRVFLAG_LOG;
s->srv_conf.logformat = LOG_FORMAT_COMMON;
+ s->srv_conf.ssl_cert_file = HTTPD_SSL_CERT;
+ s->srv_conf.ssl_key_file = HTTPD_SSL_KEY;
if (last_server_id == INT_MAX) {
yyerror("too many servers defined");
free($2);
YYERROR;
}
+ if (server_ssl_load_keypair(srv) == -1) {
+ yyerror("failed to load public/private keys "
+ "for server %s", srv->srv_conf.name);
+ YYERROR;
+ }
srv = NULL;
srv_conf = NULL;
}
-/* $OpenBSD: server.c,v 1.29 2014/08/05 15:36:59 reyk Exp $ */
+/* $OpenBSD: server.c,v 1.30 2014/08/06 02:04:42 jsing Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
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_ssl_load_keypair(struct server *srv)
+{
+ if ((srv->srv_conf.flags & SRVFLAG_SSL) == 0)
+ return (0);
+
+ if ((srv->srv_conf.ssl_cert = server_load_file(
+ srv->srv_conf.ssl_cert_file, &srv->srv_conf.ssl_cert_len)) == NULL)
+ return (-1);
+ log_debug("%s: using certificate %s", __func__,
+ srv->srv_conf.ssl_cert_file);
+
+ if ((srv->srv_conf.ssl_key = server_load_file(
+ srv->srv_conf.ssl_key_file, &srv->srv_conf.ssl_key_len)) == NULL)
+ return (-1);
+ log_debug("%s: using private key %s", __func__,
+ srv->srv_conf.ssl_key_file);
+
+ return (0);
+}
+
int
server_ssl_init(struct server *srv)
{
return (-1);
}
- /*
- * XXX Make these configurable and move keys out of the chroot.
- * XXX The RSA privsep code in relayd should be adopted to ressl.
- */
- ressl_config_set_cert_file(srv->srv_ressl_config, HTTPD_SSL_CERT);
- ressl_config_set_key_file(srv->srv_ressl_config, HTTPD_SSL_KEY);
+ 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 (ressl_configure(srv->srv_ressl_ctx, srv->srv_ressl_config) != 0) {
log_warn("%s: failed to configure SSL - %s", __func__,
return (-1);
}
+ /* We're now done with the key... */
+ explicit_bzero(srv->srv_conf.ssl_key, srv->srv_conf.ssl_key_len);
+ free(srv->srv_conf.ssl_key);
+ srv->srv_conf.ssl_key = NULL;
+ srv->srv_conf.ssl_key_len = 0;
+
return (0);
}
TAILQ_REMOVE(&srv->srv_hosts, srv_conf, entry);
/* It might point to our own "default" entry */
- if (srv_conf != &srv->srv_conf)
+ if (srv_conf != &srv->srv_conf) {
+ free(srv_conf->ssl_cert);
+ free(srv_conf->ssl_key);
free(srv_conf);
+ }
}
ressl_config_free(srv->srv_ressl_config);