1*340f5e56SDavid van Moolenbroek /* $NetBSD: ssl-bozo.c,v 1.18 2014/07/17 06:27:52 mrg Exp $ */
2*340f5e56SDavid van Moolenbroek
3*340f5e56SDavid van Moolenbroek /* $eterna: ssl-bozo.c,v 1.15 2011/11/18 09:21:15 mrg Exp $ */
4*340f5e56SDavid van Moolenbroek
5*340f5e56SDavid van Moolenbroek /*
6*340f5e56SDavid van Moolenbroek * Copyright (c) 1997-2014 Matthew R. Green
7*340f5e56SDavid van Moolenbroek * All rights reserved.
8*340f5e56SDavid van Moolenbroek *
9*340f5e56SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
10*340f5e56SDavid van Moolenbroek * modification, are permitted provided that the following conditions
11*340f5e56SDavid van Moolenbroek * are met:
12*340f5e56SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
13*340f5e56SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
14*340f5e56SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
15*340f5e56SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer and
16*340f5e56SDavid van Moolenbroek * dedication in the documentation and/or other materials provided
17*340f5e56SDavid van Moolenbroek * with the distribution.
18*340f5e56SDavid van Moolenbroek *
19*340f5e56SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20*340f5e56SDavid van Moolenbroek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*340f5e56SDavid van Moolenbroek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*340f5e56SDavid van Moolenbroek * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23*340f5e56SDavid van Moolenbroek * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24*340f5e56SDavid van Moolenbroek * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*340f5e56SDavid van Moolenbroek * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26*340f5e56SDavid van Moolenbroek * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27*340f5e56SDavid van Moolenbroek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*340f5e56SDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*340f5e56SDavid van Moolenbroek * SUCH DAMAGE.
30*340f5e56SDavid van Moolenbroek *
31*340f5e56SDavid van Moolenbroek */
32*340f5e56SDavid van Moolenbroek
33*340f5e56SDavid van Moolenbroek /* this code implements SSL and backend IO for bozohttpd */
34*340f5e56SDavid van Moolenbroek
35*340f5e56SDavid van Moolenbroek #include <stdarg.h>
36*340f5e56SDavid van Moolenbroek #include <stdio.h>
37*340f5e56SDavid van Moolenbroek #include <syslog.h>
38*340f5e56SDavid van Moolenbroek #include <unistd.h>
39*340f5e56SDavid van Moolenbroek
40*340f5e56SDavid van Moolenbroek #include "bozohttpd.h"
41*340f5e56SDavid van Moolenbroek
42*340f5e56SDavid van Moolenbroek #ifndef NO_SSL_SUPPORT
43*340f5e56SDavid van Moolenbroek
44*340f5e56SDavid van Moolenbroek #include <openssl/ssl.h>
45*340f5e56SDavid van Moolenbroek #include <openssl/err.h>
46*340f5e56SDavid van Moolenbroek
47*340f5e56SDavid van Moolenbroek #ifndef USE_ARG
48*340f5e56SDavid van Moolenbroek #define USE_ARG(x) /*LINTED*/(void)&(x)
49*340f5e56SDavid van Moolenbroek #endif
50*340f5e56SDavid van Moolenbroek
51*340f5e56SDavid van Moolenbroek /* this structure encapsulates the ssl info */
52*340f5e56SDavid van Moolenbroek typedef struct sslinfo_t {
53*340f5e56SDavid van Moolenbroek SSL_CTX *ssl_context;
54*340f5e56SDavid van Moolenbroek const SSL_METHOD *ssl_method;
55*340f5e56SDavid van Moolenbroek SSL *bozossl;
56*340f5e56SDavid van Moolenbroek char *certificate_file;
57*340f5e56SDavid van Moolenbroek char *privatekey_file;
58*340f5e56SDavid van Moolenbroek } sslinfo_t;
59*340f5e56SDavid van Moolenbroek
60*340f5e56SDavid van Moolenbroek /*
61*340f5e56SDavid van Moolenbroek * bozo_clear_ssl_queue: print the contents of the SSL error queue
62*340f5e56SDavid van Moolenbroek */
63*340f5e56SDavid van Moolenbroek static void
bozo_clear_ssl_queue(bozohttpd_t * httpd)64*340f5e56SDavid van Moolenbroek bozo_clear_ssl_queue(bozohttpd_t *httpd)
65*340f5e56SDavid van Moolenbroek {
66*340f5e56SDavid van Moolenbroek unsigned long sslcode = ERR_get_error();
67*340f5e56SDavid van Moolenbroek
68*340f5e56SDavid van Moolenbroek do {
69*340f5e56SDavid van Moolenbroek static const char sslfmt[] = "SSL Error: %s:%s:%s";
70*340f5e56SDavid van Moolenbroek
71*340f5e56SDavid van Moolenbroek if (httpd->logstderr || isatty(STDERR_FILENO)) {
72*340f5e56SDavid van Moolenbroek fprintf(stderr, sslfmt,
73*340f5e56SDavid van Moolenbroek ERR_lib_error_string(sslcode),
74*340f5e56SDavid van Moolenbroek ERR_func_error_string(sslcode),
75*340f5e56SDavid van Moolenbroek ERR_reason_error_string(sslcode));
76*340f5e56SDavid van Moolenbroek } else {
77*340f5e56SDavid van Moolenbroek syslog(LOG_ERR, sslfmt,
78*340f5e56SDavid van Moolenbroek ERR_lib_error_string(sslcode),
79*340f5e56SDavid van Moolenbroek ERR_func_error_string(sslcode),
80*340f5e56SDavid van Moolenbroek ERR_reason_error_string(sslcode));
81*340f5e56SDavid van Moolenbroek }
82*340f5e56SDavid van Moolenbroek } while (0 != (sslcode = ERR_get_error()));
83*340f5e56SDavid van Moolenbroek }
84*340f5e56SDavid van Moolenbroek
85*340f5e56SDavid van Moolenbroek /*
86*340f5e56SDavid van Moolenbroek * bozo_ssl_warn works just like bozo_warn, plus the SSL error queue
87*340f5e56SDavid van Moolenbroek */
88*340f5e56SDavid van Moolenbroek BOZO_PRINTFLIKE(2, 3) static void
bozo_ssl_warn(bozohttpd_t * httpd,const char * fmt,...)89*340f5e56SDavid van Moolenbroek bozo_ssl_warn(bozohttpd_t *httpd, const char *fmt, ...)
90*340f5e56SDavid van Moolenbroek {
91*340f5e56SDavid van Moolenbroek va_list ap;
92*340f5e56SDavid van Moolenbroek
93*340f5e56SDavid van Moolenbroek va_start(ap, fmt);
94*340f5e56SDavid van Moolenbroek if (httpd->logstderr || isatty(STDERR_FILENO)) {
95*340f5e56SDavid van Moolenbroek vfprintf(stderr, fmt, ap);
96*340f5e56SDavid van Moolenbroek fputs("\n", stderr);
97*340f5e56SDavid van Moolenbroek } else
98*340f5e56SDavid van Moolenbroek vsyslog(LOG_ERR, fmt, ap);
99*340f5e56SDavid van Moolenbroek va_end(ap);
100*340f5e56SDavid van Moolenbroek
101*340f5e56SDavid van Moolenbroek bozo_clear_ssl_queue(httpd);
102*340f5e56SDavid van Moolenbroek }
103*340f5e56SDavid van Moolenbroek
104*340f5e56SDavid van Moolenbroek
105*340f5e56SDavid van Moolenbroek /*
106*340f5e56SDavid van Moolenbroek * bozo_ssl_err works just like bozo_err, plus the SSL error queue
107*340f5e56SDavid van Moolenbroek */
108*340f5e56SDavid van Moolenbroek BOZO_PRINTFLIKE(3, 4) BOZO_DEAD static void
bozo_ssl_err(bozohttpd_t * httpd,int code,const char * fmt,...)109*340f5e56SDavid van Moolenbroek bozo_ssl_err(bozohttpd_t *httpd, int code, const char *fmt, ...)
110*340f5e56SDavid van Moolenbroek {
111*340f5e56SDavid van Moolenbroek va_list ap;
112*340f5e56SDavid van Moolenbroek
113*340f5e56SDavid van Moolenbroek va_start(ap, fmt);
114*340f5e56SDavid van Moolenbroek if (httpd->logstderr || isatty(STDERR_FILENO)) {
115*340f5e56SDavid van Moolenbroek vfprintf(stderr, fmt, ap);
116*340f5e56SDavid van Moolenbroek fputs("\n", stderr);
117*340f5e56SDavid van Moolenbroek } else
118*340f5e56SDavid van Moolenbroek vsyslog(LOG_ERR, fmt, ap);
119*340f5e56SDavid van Moolenbroek va_end(ap);
120*340f5e56SDavid van Moolenbroek
121*340f5e56SDavid van Moolenbroek bozo_clear_ssl_queue(httpd);
122*340f5e56SDavid van Moolenbroek exit(code);
123*340f5e56SDavid van Moolenbroek }
124*340f5e56SDavid van Moolenbroek
125*340f5e56SDavid van Moolenbroek /*
126*340f5e56SDavid van Moolenbroek * bozo_check_error_queue: print warnings if the error isn't expected
127*340f5e56SDavid van Moolenbroek */
128*340f5e56SDavid van Moolenbroek static void
bozo_check_error_queue(bozohttpd_t * httpd,const char * tag,int ret)129*340f5e56SDavid van Moolenbroek bozo_check_error_queue(bozohttpd_t *httpd, const char *tag, int ret)
130*340f5e56SDavid van Moolenbroek {
131*340f5e56SDavid van Moolenbroek if (ret > 0)
132*340f5e56SDavid van Moolenbroek return;
133*340f5e56SDavid van Moolenbroek
134*340f5e56SDavid van Moolenbroek const sslinfo_t *sslinfo = httpd->sslinfo;
135*340f5e56SDavid van Moolenbroek const int sslerr = SSL_get_error(sslinfo->bozossl, ret);
136*340f5e56SDavid van Moolenbroek
137*340f5e56SDavid van Moolenbroek if (sslerr != SSL_ERROR_ZERO_RETURN &&
138*340f5e56SDavid van Moolenbroek sslerr != SSL_ERROR_SYSCALL &&
139*340f5e56SDavid van Moolenbroek sslerr != SSL_ERROR_NONE)
140*340f5e56SDavid van Moolenbroek bozo_ssl_warn(httpd, "%s: SSL_ERROR %d", tag, sslerr);
141*340f5e56SDavid van Moolenbroek }
142*340f5e56SDavid van Moolenbroek
143*340f5e56SDavid van Moolenbroek static BOZO_PRINTFLIKE(2, 0) int
bozo_ssl_printf(bozohttpd_t * httpd,const char * fmt,va_list ap)144*340f5e56SDavid van Moolenbroek bozo_ssl_printf(bozohttpd_t *httpd, const char * fmt, va_list ap)
145*340f5e56SDavid van Moolenbroek {
146*340f5e56SDavid van Moolenbroek char *buf;
147*340f5e56SDavid van Moolenbroek int nbytes;
148*340f5e56SDavid van Moolenbroek
149*340f5e56SDavid van Moolenbroek if ((nbytes = vasprintf(&buf, fmt, ap)) != -1) {
150*340f5e56SDavid van Moolenbroek const sslinfo_t *sslinfo = httpd->sslinfo;
151*340f5e56SDavid van Moolenbroek int ret = SSL_write(sslinfo->bozossl, buf, nbytes);
152*340f5e56SDavid van Moolenbroek bozo_check_error_queue(httpd, "write", ret);
153*340f5e56SDavid van Moolenbroek }
154*340f5e56SDavid van Moolenbroek
155*340f5e56SDavid van Moolenbroek free(buf);
156*340f5e56SDavid van Moolenbroek
157*340f5e56SDavid van Moolenbroek return nbytes;
158*340f5e56SDavid van Moolenbroek }
159*340f5e56SDavid van Moolenbroek
160*340f5e56SDavid van Moolenbroek static ssize_t
bozo_ssl_read(bozohttpd_t * httpd,int fd,void * buf,size_t nbytes)161*340f5e56SDavid van Moolenbroek bozo_ssl_read(bozohttpd_t *httpd, int fd, void *buf, size_t nbytes)
162*340f5e56SDavid van Moolenbroek {
163*340f5e56SDavid van Moolenbroek const sslinfo_t *sslinfo = httpd->sslinfo;
164*340f5e56SDavid van Moolenbroek int ret;
165*340f5e56SDavid van Moolenbroek
166*340f5e56SDavid van Moolenbroek USE_ARG(fd);
167*340f5e56SDavid van Moolenbroek ret = SSL_read(sslinfo->bozossl, buf, (int)nbytes);
168*340f5e56SDavid van Moolenbroek bozo_check_error_queue(httpd, "read", ret);
169*340f5e56SDavid van Moolenbroek
170*340f5e56SDavid van Moolenbroek return (ssize_t)ret;
171*340f5e56SDavid van Moolenbroek }
172*340f5e56SDavid van Moolenbroek
173*340f5e56SDavid van Moolenbroek static ssize_t
bozo_ssl_write(bozohttpd_t * httpd,int fd,const void * buf,size_t nbytes)174*340f5e56SDavid van Moolenbroek bozo_ssl_write(bozohttpd_t *httpd, int fd, const void *buf, size_t nbytes)
175*340f5e56SDavid van Moolenbroek {
176*340f5e56SDavid van Moolenbroek const sslinfo_t *sslinfo = httpd->sslinfo;
177*340f5e56SDavid van Moolenbroek int ret;
178*340f5e56SDavid van Moolenbroek
179*340f5e56SDavid van Moolenbroek USE_ARG(fd);
180*340f5e56SDavid van Moolenbroek ret = SSL_write(sslinfo->bozossl, buf, (int)nbytes);
181*340f5e56SDavid van Moolenbroek bozo_check_error_queue(httpd, "write", ret);
182*340f5e56SDavid van Moolenbroek
183*340f5e56SDavid van Moolenbroek return (ssize_t)ret;
184*340f5e56SDavid van Moolenbroek }
185*340f5e56SDavid van Moolenbroek
186*340f5e56SDavid van Moolenbroek void
bozo_ssl_init(bozohttpd_t * httpd)187*340f5e56SDavid van Moolenbroek bozo_ssl_init(bozohttpd_t *httpd)
188*340f5e56SDavid van Moolenbroek {
189*340f5e56SDavid van Moolenbroek sslinfo_t *sslinfo = httpd->sslinfo;
190*340f5e56SDavid van Moolenbroek
191*340f5e56SDavid van Moolenbroek if (sslinfo == NULL || !sslinfo->certificate_file)
192*340f5e56SDavid van Moolenbroek return;
193*340f5e56SDavid van Moolenbroek SSL_library_init();
194*340f5e56SDavid van Moolenbroek SSL_load_error_strings();
195*340f5e56SDavid van Moolenbroek
196*340f5e56SDavid van Moolenbroek sslinfo->ssl_method = SSLv23_server_method();
197*340f5e56SDavid van Moolenbroek sslinfo->ssl_context = SSL_CTX_new(sslinfo->ssl_method);
198*340f5e56SDavid van Moolenbroek
199*340f5e56SDavid van Moolenbroek if (NULL == sslinfo->ssl_context)
200*340f5e56SDavid van Moolenbroek bozo_ssl_err(httpd, EXIT_FAILURE,
201*340f5e56SDavid van Moolenbroek "SSL context creation failed");
202*340f5e56SDavid van Moolenbroek
203*340f5e56SDavid van Moolenbroek if (1 != SSL_CTX_use_certificate_chain_file(sslinfo->ssl_context,
204*340f5e56SDavid van Moolenbroek sslinfo->certificate_file))
205*340f5e56SDavid van Moolenbroek bozo_ssl_err(httpd, EXIT_FAILURE,
206*340f5e56SDavid van Moolenbroek "Unable to use certificate file '%s'",
207*340f5e56SDavid van Moolenbroek sslinfo->certificate_file);
208*340f5e56SDavid van Moolenbroek
209*340f5e56SDavid van Moolenbroek if (1 != SSL_CTX_use_PrivateKey_file(sslinfo->ssl_context,
210*340f5e56SDavid van Moolenbroek sslinfo->privatekey_file, SSL_FILETYPE_PEM))
211*340f5e56SDavid van Moolenbroek bozo_ssl_err(httpd, EXIT_FAILURE,
212*340f5e56SDavid van Moolenbroek "Unable to use private key file '%s'",
213*340f5e56SDavid van Moolenbroek sslinfo->privatekey_file);
214*340f5e56SDavid van Moolenbroek
215*340f5e56SDavid van Moolenbroek /* check consistency of key vs certificate */
216*340f5e56SDavid van Moolenbroek if (!SSL_CTX_check_private_key(sslinfo->ssl_context))
217*340f5e56SDavid van Moolenbroek bozo_ssl_err(httpd, EXIT_FAILURE,
218*340f5e56SDavid van Moolenbroek "Check private key failed");
219*340f5e56SDavid van Moolenbroek }
220*340f5e56SDavid van Moolenbroek
221*340f5e56SDavid van Moolenbroek /*
222*340f5e56SDavid van Moolenbroek * returns non-zero for failure
223*340f5e56SDavid van Moolenbroek */
224*340f5e56SDavid van Moolenbroek int
bozo_ssl_accept(bozohttpd_t * httpd)225*340f5e56SDavid van Moolenbroek bozo_ssl_accept(bozohttpd_t *httpd)
226*340f5e56SDavid van Moolenbroek {
227*340f5e56SDavid van Moolenbroek sslinfo_t *sslinfo = httpd->sslinfo;
228*340f5e56SDavid van Moolenbroek
229*340f5e56SDavid van Moolenbroek if (sslinfo == NULL || !sslinfo->ssl_context)
230*340f5e56SDavid van Moolenbroek return 0;
231*340f5e56SDavid van Moolenbroek
232*340f5e56SDavid van Moolenbroek sslinfo->bozossl = SSL_new(sslinfo->ssl_context);
233*340f5e56SDavid van Moolenbroek if (sslinfo->bozossl == NULL)
234*340f5e56SDavid van Moolenbroek bozo_err(httpd, 1, "SSL_new failed");
235*340f5e56SDavid van Moolenbroek
236*340f5e56SDavid van Moolenbroek SSL_set_rfd(sslinfo->bozossl, 0);
237*340f5e56SDavid van Moolenbroek SSL_set_wfd(sslinfo->bozossl, 1);
238*340f5e56SDavid van Moolenbroek
239*340f5e56SDavid van Moolenbroek const int ret = SSL_accept(sslinfo->bozossl);
240*340f5e56SDavid van Moolenbroek bozo_check_error_queue(httpd, "accept", ret);
241*340f5e56SDavid van Moolenbroek
242*340f5e56SDavid van Moolenbroek return ret != 1;
243*340f5e56SDavid van Moolenbroek }
244*340f5e56SDavid van Moolenbroek
245*340f5e56SDavid van Moolenbroek void
bozo_ssl_destroy(bozohttpd_t * httpd)246*340f5e56SDavid van Moolenbroek bozo_ssl_destroy(bozohttpd_t *httpd)
247*340f5e56SDavid van Moolenbroek {
248*340f5e56SDavid van Moolenbroek const sslinfo_t *sslinfo = httpd->sslinfo;
249*340f5e56SDavid van Moolenbroek
250*340f5e56SDavid van Moolenbroek if (sslinfo && sslinfo->bozossl)
251*340f5e56SDavid van Moolenbroek SSL_free(sslinfo->bozossl);
252*340f5e56SDavid van Moolenbroek }
253*340f5e56SDavid van Moolenbroek
254*340f5e56SDavid van Moolenbroek void
bozo_ssl_set_opts(bozohttpd_t * httpd,const char * cert,const char * priv)255*340f5e56SDavid van Moolenbroek bozo_ssl_set_opts(bozohttpd_t *httpd, const char *cert, const char *priv)
256*340f5e56SDavid van Moolenbroek {
257*340f5e56SDavid van Moolenbroek sslinfo_t *sslinfo = httpd->sslinfo;
258*340f5e56SDavid van Moolenbroek
259*340f5e56SDavid van Moolenbroek if (sslinfo == NULL) {
260*340f5e56SDavid van Moolenbroek sslinfo = bozomalloc(httpd, sizeof(*sslinfo));
261*340f5e56SDavid van Moolenbroek if (sslinfo == NULL)
262*340f5e56SDavid van Moolenbroek bozo_err(httpd, 1, "sslinfo allocation failed");
263*340f5e56SDavid van Moolenbroek httpd->sslinfo = sslinfo;
264*340f5e56SDavid van Moolenbroek }
265*340f5e56SDavid van Moolenbroek sslinfo->certificate_file = strdup(cert);
266*340f5e56SDavid van Moolenbroek sslinfo->privatekey_file = strdup(priv);
267*340f5e56SDavid van Moolenbroek debug((httpd, DEBUG_NORMAL, "using cert/priv files: %s & %s",
268*340f5e56SDavid van Moolenbroek sslinfo->certificate_file,
269*340f5e56SDavid van Moolenbroek sslinfo->privatekey_file));
270*340f5e56SDavid van Moolenbroek if (!httpd->bindport)
271*340f5e56SDavid van Moolenbroek httpd->bindport = strdup("https");
272*340f5e56SDavid van Moolenbroek }
273*340f5e56SDavid van Moolenbroek
274*340f5e56SDavid van Moolenbroek #endif /* NO_SSL_SUPPORT */
275*340f5e56SDavid van Moolenbroek
276*340f5e56SDavid van Moolenbroek int
bozo_printf(bozohttpd_t * httpd,const char * fmt,...)277*340f5e56SDavid van Moolenbroek bozo_printf(bozohttpd_t *httpd, const char *fmt, ...)
278*340f5e56SDavid van Moolenbroek {
279*340f5e56SDavid van Moolenbroek va_list args;
280*340f5e56SDavid van Moolenbroek int cc;
281*340f5e56SDavid van Moolenbroek
282*340f5e56SDavid van Moolenbroek va_start(args, fmt);
283*340f5e56SDavid van Moolenbroek #ifndef NO_SSL_SUPPORT
284*340f5e56SDavid van Moolenbroek if (httpd->sslinfo)
285*340f5e56SDavid van Moolenbroek cc = bozo_ssl_printf(httpd, fmt, args);
286*340f5e56SDavid van Moolenbroek else
287*340f5e56SDavid van Moolenbroek #endif
288*340f5e56SDavid van Moolenbroek cc = vprintf(fmt, args);
289*340f5e56SDavid van Moolenbroek va_end(args);
290*340f5e56SDavid van Moolenbroek return cc;
291*340f5e56SDavid van Moolenbroek }
292*340f5e56SDavid van Moolenbroek
293*340f5e56SDavid van Moolenbroek ssize_t
bozo_read(bozohttpd_t * httpd,int fd,void * buf,size_t len)294*340f5e56SDavid van Moolenbroek bozo_read(bozohttpd_t *httpd, int fd, void *buf, size_t len)
295*340f5e56SDavid van Moolenbroek {
296*340f5e56SDavid van Moolenbroek #ifndef NO_SSL_SUPPORT
297*340f5e56SDavid van Moolenbroek if (httpd->sslinfo)
298*340f5e56SDavid van Moolenbroek return bozo_ssl_read(httpd, fd, buf, len);
299*340f5e56SDavid van Moolenbroek #endif
300*340f5e56SDavid van Moolenbroek return read(fd, buf, len);
301*340f5e56SDavid van Moolenbroek }
302*340f5e56SDavid van Moolenbroek
303*340f5e56SDavid van Moolenbroek ssize_t
bozo_write(bozohttpd_t * httpd,int fd,const void * buf,size_t len)304*340f5e56SDavid van Moolenbroek bozo_write(bozohttpd_t *httpd, int fd, const void *buf, size_t len)
305*340f5e56SDavid van Moolenbroek {
306*340f5e56SDavid van Moolenbroek #ifndef NO_SSL_SUPPORT
307*340f5e56SDavid van Moolenbroek if (httpd->sslinfo)
308*340f5e56SDavid van Moolenbroek return bozo_ssl_write(httpd, fd, buf, len);
309*340f5e56SDavid van Moolenbroek #endif
310*340f5e56SDavid van Moolenbroek return write(fd, buf, len);
311*340f5e56SDavid van Moolenbroek }
312*340f5e56SDavid van Moolenbroek
313*340f5e56SDavid van Moolenbroek int
bozo_flush(bozohttpd_t * httpd,FILE * fp)314*340f5e56SDavid van Moolenbroek bozo_flush(bozohttpd_t *httpd, FILE *fp)
315*340f5e56SDavid van Moolenbroek {
316*340f5e56SDavid van Moolenbroek #ifndef NO_SSL_SUPPORT
317*340f5e56SDavid van Moolenbroek if (httpd->sslinfo)
318*340f5e56SDavid van Moolenbroek return 0;
319*340f5e56SDavid van Moolenbroek #endif
320*340f5e56SDavid van Moolenbroek return fflush(fp);
321*340f5e56SDavid van Moolenbroek }
322