Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/httpd rewrite much of the SSL code:
details: https://anonhg.NetBSD.org/src/rev/98675495ecac
branches: trunk
changeset: 330656:98675495ecac
user: mrg <mrg%NetBSD.org@localhost>
date: Thu Jul 17 06:27:52 2014 +0000
description:
rewrite much of the SSL code:
- handle errors in many places they weren't properly
- make SSL_accept() an error the main code notices
- expand bozo_ssl_err() to include bozo_ssl_warn(), bozo_clear_ssl_queue()
- remove empty bozo_ssl_flush()
diffstat:
libexec/httpd/bozohttpd.c | 5 +-
libexec/httpd/bozohttpd.h | 6 +-
libexec/httpd/ssl-bozo.c | 158 ++++++++++++++++++++++++++++-----------------
3 files changed, 104 insertions(+), 65 deletions(-)
diffs (291 lines):
diff -r 8e74edcd3b63 -r 98675495ecac libexec/httpd/bozohttpd.c
--- a/libexec/httpd/bozohttpd.c Thu Jul 17 06:24:57 2014 +0000
+++ b/libexec/httpd/bozohttpd.c Thu Jul 17 06:27:52 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bozohttpd.c,v 1.54 2014/07/08 14:06:17 mrg Exp $ */
+/* $NetBSD: bozohttpd.c,v 1.55 2014/07/17 06:27:52 mrg Exp $ */
/* $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $ */
@@ -527,7 +527,8 @@
*/
if (bozo_daemon_fork(httpd))
return NULL;
- bozo_ssl_accept(httpd);
+ if (bozo_ssl_accept(httpd))
+ return NULL;
request = bozomalloc(httpd, sizeof(*request));
memset(request, 0, sizeof(*request));
diff -r 8e74edcd3b63 -r 98675495ecac libexec/httpd/bozohttpd.h
--- a/libexec/httpd/bozohttpd.h Thu Jul 17 06:24:57 2014 +0000
+++ b/libexec/httpd/bozohttpd.h Thu Jul 17 06:27:52 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bozohttpd.h,v 1.32 2014/02/09 01:46:10 mrg Exp $ */
+/* $NetBSD: bozohttpd.h,v 1.33 2014/07/17 06:27:52 mrg Exp $ */
/* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */
@@ -235,12 +235,12 @@
#ifdef NO_SSL_SUPPORT
#define bozo_ssl_set_opts(w, x, y) do { /* nothing */ } while (0)
#define bozo_ssl_init(x) do { /* nothing */ } while (0)
-#define bozo_ssl_accept(x) do { /* nothing */ } while (0)
+#define bozo_ssl_accept(x) (0)
#define bozo_ssl_destroy(x) do { /* nothing */ } while (0)
#else
void bozo_ssl_set_opts(bozohttpd_t *, const char *, const char *);
void bozo_ssl_init(bozohttpd_t *);
-void bozo_ssl_accept(bozohttpd_t *);
+int bozo_ssl_accept(bozohttpd_t *);
void bozo_ssl_destroy(bozohttpd_t *);
#endif
diff -r 8e74edcd3b63 -r 98675495ecac libexec/httpd/ssl-bozo.c
--- a/libexec/httpd/ssl-bozo.c Thu Jul 17 06:24:57 2014 +0000
+++ b/libexec/httpd/ssl-bozo.c Thu Jul 17 06:27:52 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ssl-bozo.c,v 1.17 2014/07/17 06:14:46 mrg Exp $ */
+/* $NetBSD: ssl-bozo.c,v 1.18 2014/07/17 06:27:52 mrg Exp $ */
/* $eterna: ssl-bozo.c,v 1.15 2011/11/18 09:21:15 mrg Exp $ */
@@ -30,7 +30,7 @@
*
*/
-/* this code implements SSL for bozohttpd */
+/* this code implements SSL and backend IO for bozohttpd */
#include <stdarg.h>
#include <stdio.h>
@@ -58,26 +58,13 @@
} sslinfo_t;
/*
- * bozo_ssl_err
- *
- * bozo_ssl_err works just like bozo_err except in addition to printing
- * the error provided by the caller at the point of error it pops and
- * prints all errors from the SSL error queue.
+ * bozo_clear_ssl_queue: print the contents of the SSL error queue
*/
-BOZO_PRINTFLIKE(3, 4) BOZO_DEAD static void
-bozo_ssl_err(bozohttpd_t *httpd, int code, const char *fmt, ...)
+static void
+bozo_clear_ssl_queue(bozohttpd_t *httpd)
{
- va_list ap;
+ unsigned long sslcode = ERR_get_error();
- va_start(ap, fmt);
- if (httpd->logstderr || isatty(STDERR_FILENO)) {
- vfprintf(stderr, fmt, ap);
- fputs("\n", stderr);
- } else
- vsyslog(LOG_ERR, fmt, ap);
- va_end(ap);
-
- unsigned int sslcode = ERR_get_error();
do {
static const char sslfmt[] = "SSL Error: %s:%s:%s";
@@ -93,19 +80,77 @@
ERR_reason_error_string(sslcode));
}
} while (0 != (sslcode = ERR_get_error()));
+}
+
+/*
+ * bozo_ssl_warn works just like bozo_warn, plus the SSL error queue
+ */
+BOZO_PRINTFLIKE(2, 3) static void
+bozo_ssl_warn(bozohttpd_t *httpd, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (httpd->logstderr || isatty(STDERR_FILENO)) {
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ } else
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+
+ bozo_clear_ssl_queue(httpd);
+}
+
+
+/*
+ * bozo_ssl_err works just like bozo_err, plus the SSL error queue
+ */
+BOZO_PRINTFLIKE(3, 4) BOZO_DEAD static void
+bozo_ssl_err(bozohttpd_t *httpd, int code, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (httpd->logstderr || isatty(STDERR_FILENO)) {
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ } else
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+
+ bozo_clear_ssl_queue(httpd);
exit(code);
}
+/*
+ * bozo_check_error_queue: print warnings if the error isn't expected
+ */
+static void
+bozo_check_error_queue(bozohttpd_t *httpd, const char *tag, int ret)
+{
+ if (ret > 0)
+ return;
+
+ const sslinfo_t *sslinfo = httpd->sslinfo;
+ const int sslerr = SSL_get_error(sslinfo->bozossl, ret);
+
+ if (sslerr != SSL_ERROR_ZERO_RETURN &&
+ sslerr != SSL_ERROR_SYSCALL &&
+ sslerr != SSL_ERROR_NONE)
+ bozo_ssl_warn(httpd, "%s: SSL_ERROR %d", tag, sslerr);
+}
+
static BOZO_PRINTFLIKE(2, 0) int
bozo_ssl_printf(bozohttpd_t *httpd, const char * fmt, va_list ap)
{
- const sslinfo_t *sslinfo = httpd->sslinfo;
- char *buf;
- int nbytes;
+ char *buf;
+ int nbytes;
- /* XXX we need more elegant/proper handling of SSL_write return */
- if ((nbytes = vasprintf(&buf, fmt, ap)) != -1)
- SSL_write(sslinfo->bozossl, buf, nbytes);
+ if ((nbytes = vasprintf(&buf, fmt, ap)) != -1) {
+ const sslinfo_t *sslinfo = httpd->sslinfo;
+ int ret = SSL_write(sslinfo->bozossl, buf, nbytes);
+ bozo_check_error_queue(httpd, "write", ret);
+ }
free(buf);
@@ -116,42 +161,26 @@
bozo_ssl_read(bozohttpd_t *httpd, int fd, void *buf, size_t nbytes)
{
const sslinfo_t *sslinfo = httpd->sslinfo;
- ssize_t rbytes;
+ int ret;
USE_ARG(fd);
- /* XXX we need elegant/proper handling of SSL_read return */
- rbytes = (ssize_t)SSL_read(sslinfo->bozossl, buf, (int)nbytes);
- if (rbytes < 1) {
- if (SSL_get_error(sslinfo->bozossl, rbytes) ==
- SSL_ERROR_WANT_READ)
- bozo_warn(httpd, "SSL_ERROR_WANT_READ");
- else
- bozo_warn(httpd, "SSL_ERROR OTHER");
- }
+ ret = SSL_read(sslinfo->bozossl, buf, (int)nbytes);
+ bozo_check_error_queue(httpd, "read", ret);
- return rbytes;
+ return (ssize_t)ret;
}
static ssize_t
bozo_ssl_write(bozohttpd_t *httpd, int fd, const void *buf, size_t nbytes)
{
const sslinfo_t *sslinfo = httpd->sslinfo;
- ssize_t wbytes;
+ int ret;
USE_ARG(fd);
- /* XXX we need elegant/proper handling of SSL_write return */
- wbytes = (ssize_t)SSL_write(sslinfo->bozossl, buf, (int)nbytes);
-
- return wbytes;
-}
+ ret = SSL_write(sslinfo->bozossl, buf, (int)nbytes);
+ bozo_check_error_queue(httpd, "write", ret);
-static int
-bozo_ssl_flush(bozohttpd_t *httpd, FILE *fp)
-{
- USE_ARG(httpd);
- USE_ARG(fp);
- /* nothing to see here, move right along */
- return 0;
+ return (ssize_t)ret;
}
void
@@ -167,7 +196,6 @@
sslinfo->ssl_method = SSLv23_server_method();
sslinfo->ssl_context = SSL_CTX_new(sslinfo->ssl_method);
- /* XXX we need to learn how to check the SSL stack for more info */
if (NULL == sslinfo->ssl_context)
bozo_ssl_err(httpd, EXIT_FAILURE,
"SSL context creation failed");
@@ -190,17 +218,28 @@
"Check private key failed");
}
-void
+/*
+ * returns non-zero for failure
+ */
+int
bozo_ssl_accept(bozohttpd_t *httpd)
{
sslinfo_t *sslinfo = httpd->sslinfo;
- if (sslinfo != NULL && sslinfo->ssl_context) {
- sslinfo->bozossl = SSL_new(sslinfo->ssl_context);
- SSL_set_rfd(sslinfo->bozossl, 0);
- SSL_set_wfd(sslinfo->bozossl, 1);
- SSL_accept(sslinfo->bozossl);
- }
+ if (sslinfo == NULL || !sslinfo->ssl_context)
+ return 0;
+
+ sslinfo->bozossl = SSL_new(sslinfo->ssl_context);
+ if (sslinfo->bozossl == NULL)
+ bozo_err(httpd, 1, "SSL_new failed");
+
+ SSL_set_rfd(sslinfo->bozossl, 0);
+ SSL_set_wfd(sslinfo->bozossl, 1);
+
+ const int ret = SSL_accept(sslinfo->bozossl);
+ bozo_check_error_queue(httpd, "accept", ret);
+
+ return ret != 1;
}
void
@@ -219,9 +258,8 @@
if (sslinfo == NULL) {
sslinfo = bozomalloc(httpd, sizeof(*sslinfo));
- if (sslinfo == NULL) {
+ if (sslinfo == NULL)
bozo_err(httpd, 1, "sslinfo allocation failed");
- }
httpd->sslinfo = sslinfo;
}
sslinfo->certificate_file = strdup(cert);
@@ -277,7 +315,7 @@
{
#ifndef NO_SSL_SUPPORT
if (httpd->sslinfo)
- return bozo_ssl_flush(httpd, fp);
+ return 0;
#endif
return fflush(fp);
}
Home |
Main Index |
Thread Index |
Old Index