Annotation of embedaddon/lighttpd/src/network.c, revision 1.1.1.1
1.1 misho 1: #include "network.h"
2: #include "fdevent.h"
3: #include "log.h"
4: #include "connections.h"
5: #include "plugin.h"
6: #include "joblist.h"
7: #include "configfile.h"
8:
9: #include "network_backends.h"
10: #include "sys-mmap.h"
11: #include "sys-socket.h"
12:
13: #include <sys/types.h>
14: #include <sys/stat.h>
15: #include <sys/time.h>
16:
17: #include <errno.h>
18: #include <fcntl.h>
19: #include <unistd.h>
20: #include <string.h>
21: #include <stdlib.h>
22: #include <assert.h>
23:
24: #ifdef USE_OPENSSL
25: # include <openssl/ssl.h>
26: # include <openssl/err.h>
27: # include <openssl/rand.h>
28: # ifndef OPENSSL_NO_DH
29: # include <openssl/dh.h>
30: # endif
31: # include <openssl/bn.h>
32:
33: # if OPENSSL_VERSION_NUMBER >= 0x0090800fL
34: # ifndef OPENSSL_NO_ECDH
35: # include <openssl/ecdh.h>
36: # endif
37: # endif
38: #endif
39:
40: #ifdef USE_OPENSSL
41: static void ssl_info_callback(const SSL *ssl, int where, int ret) {
42: UNUSED(ret);
43:
44: if (0 != (where & SSL_CB_HANDSHAKE_START)) {
45: connection *con = SSL_get_app_data(ssl);
46: ++con->renegotiations;
47: }
48: }
49: #endif
50:
51: static handler_t network_server_handle_fdevent(server *srv, void *context, int revents) {
52: server_socket *srv_socket = (server_socket *)context;
53: connection *con;
54: int loops = 0;
55:
56: UNUSED(context);
57:
58: if (0 == (revents & FDEVENT_IN)) {
59: log_error_write(srv, __FILE__, __LINE__, "sdd",
60: "strange event for server socket",
61: srv_socket->fd,
62: revents);
63: return HANDLER_ERROR;
64: }
65:
66: /* accept()s at most 100 connections directly
67: *
68: * we jump out after 100 to give the waiting connections a chance */
69: for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) {
70: handler_t r;
71:
72: connection_state_machine(srv, con);
73:
74: switch(r = plugins_call_handle_joblist(srv, con)) {
75: case HANDLER_FINISHED:
76: case HANDLER_GO_ON:
77: break;
78: default:
79: log_error_write(srv, __FILE__, __LINE__, "d", r);
80: break;
81: }
82: }
83: return HANDLER_GO_ON;
84: }
85:
86: #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
87: static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
88: const char *servername;
89: connection *con = (connection *) SSL_get_app_data(ssl);
90: UNUSED(al);
91:
92: buffer_copy_string(con->uri.scheme, "https");
93:
94: if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
95: #if 0
96: /* this "error" just means the client didn't support it */
97: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
98: "failed to get TLS server name");
99: #endif
100: return SSL_TLSEXT_ERR_NOACK;
101: }
102: buffer_copy_string(con->tlsext_server_name, servername);
103: buffer_to_lower(con->tlsext_server_name);
104:
105: /* Sometimes this is still set, confusing COMP_HTTP_HOST */
106: buffer_reset(con->uri.authority);
107:
108: config_cond_cache_reset(srv, con);
109: config_setup_connection(srv, con);
110:
111: config_patch_connection(srv, con, COMP_SERVER_SOCKET);
112: config_patch_connection(srv, con, COMP_HTTP_SCHEME);
113: config_patch_connection(srv, con, COMP_HTTP_HOST);
114:
115: if (NULL == con->conf.ssl_ctx) {
116: /* ssl_ctx <=> pemfile was set <=> ssl_ctx got patched: so this should never happen */
117: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
118: "null SSL_CTX for TLS server name", con->tlsext_server_name);
119: return SSL_TLSEXT_ERR_ALERT_FATAL;
120: }
121:
122: /* switch to new SSL_CTX in reaction to a client's server_name extension */
123: if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) {
124: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
125: "failed to set SSL_CTX for TLS server name", con->tlsext_server_name);
126: return SSL_TLSEXT_ERR_ALERT_FATAL;
127: }
128:
129: return SSL_TLSEXT_ERR_OK;
130: }
131: #endif
132:
133: static int network_server_init(server *srv, buffer *host_token, specific_config *s) {
134: int val;
135: socklen_t addr_len;
136: server_socket *srv_socket;
137: char *sp;
138: unsigned int port = 0;
139: const char *host;
140: buffer *b;
141: int is_unix_domain_socket = 0;
142: int fd;
143:
144: #ifdef __WIN32
145: WORD wVersionRequested;
146: WSADATA wsaData;
147: int err;
148:
149: wVersionRequested = MAKEWORD( 2, 2 );
150:
151: err = WSAStartup( wVersionRequested, &wsaData );
152: if ( err != 0 ) {
153: /* Tell the user that we could not find a usable */
154: /* WinSock DLL. */
155: return -1;
156: }
157: #endif
158:
159: srv_socket = calloc(1, sizeof(*srv_socket));
160: srv_socket->fd = -1;
161: srv_socket->fde_ndx = -1;
162:
163: srv_socket->srv_token = buffer_init();
164: buffer_copy_string_buffer(srv_socket->srv_token, host_token);
165:
166: b = buffer_init();
167: buffer_copy_string_buffer(b, host_token);
168:
169: /* ipv4:port
170: * [ipv6]:port
171: */
172: if (NULL == (sp = strrchr(b->ptr, ':'))) {
173: log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b);
174:
175: goto error_free_socket;
176: }
177:
178: host = b->ptr;
179:
180: /* check for [ and ] */
181: if (b->ptr[0] == '[' && *(sp-1) == ']') {
182: *(sp-1) = '\0';
183: host++;
184:
185: s->use_ipv6 = 1;
186: }
187:
188: *(sp++) = '\0';
189:
190: port = strtol(sp, NULL, 10);
191:
192: if (host[0] == '/') {
193: /* host is a unix-domain-socket */
194: is_unix_domain_socket = 1;
195: } else if (port == 0 || port > 65535) {
196: log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port);
197:
198: goto error_free_socket;
199: }
200:
201: if (*host == '\0') host = NULL;
202:
203: if (is_unix_domain_socket) {
204: #ifdef HAVE_SYS_UN_H
205:
206: srv_socket->addr.plain.sa_family = AF_UNIX;
207:
208: if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
209: log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
210: goto error_free_socket;
211: }
212: #else
213: log_error_write(srv, __FILE__, __LINE__, "s",
214: "ERROR: Unix Domain sockets are not supported.");
215: goto error_free_socket;
216: #endif
217: }
218:
219: #ifdef HAVE_IPV6
220: if (s->use_ipv6) {
221: srv_socket->addr.plain.sa_family = AF_INET6;
222:
223: if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
224: log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
225: goto error_free_socket;
226: }
227: srv_socket->use_ipv6 = 1;
228: }
229: #endif
230:
231: if (srv_socket->fd == -1) {
232: srv_socket->addr.plain.sa_family = AF_INET;
233: if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
234: log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
235: goto error_free_socket;
236: }
237: }
238:
239: #ifdef FD_CLOEXEC
240: /* set FD_CLOEXEC now, fdevent_fcntl_set is called later; needed for pipe-logger forks */
241: fcntl(srv_socket->fd, F_SETFD, FD_CLOEXEC);
242: #endif
243:
244: /* */
245: srv->cur_fds = srv_socket->fd;
246:
247: val = 1;
248: if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
249: log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(SO_REUSEADDR) failed:", strerror(errno));
250: goto error_free_socket;
251: }
252:
253: switch(srv_socket->addr.plain.sa_family) {
254: #ifdef HAVE_IPV6
255: case AF_INET6:
256: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in6));
257: srv_socket->addr.ipv6.sin6_family = AF_INET6;
258: if (host == NULL) {
259: srv_socket->addr.ipv6.sin6_addr = in6addr_any;
260: log_error_write(srv, __FILE__, __LINE__, "s", "warning: please use server.use-ipv6 only for hostnames, not without server.bind / empty address; your config will break if the kernel default for IPV6_V6ONLY changes");
261: } else {
262: struct addrinfo hints, *res;
263: int r;
264:
265: if (s->set_v6only) {
266: val = 1;
267: if (-1 == setsockopt(srv_socket->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) {
268: log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(IPV6_V6ONLY) failed:", strerror(errno));
269: goto error_free_socket;
270: }
271: } else {
272: log_error_write(srv, __FILE__, __LINE__, "s", "warning: server.set-v6only will be removed soon, update your config to have different sockets for ipv4 and ipv6");
273: }
274:
275: memset(&hints, 0, sizeof(hints));
276:
277: hints.ai_family = AF_INET6;
278: hints.ai_socktype = SOCK_STREAM;
279: hints.ai_protocol = IPPROTO_TCP;
280:
281: if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
282: log_error_write(srv, __FILE__, __LINE__,
283: "sssss", "getaddrinfo failed: ",
284: gai_strerror(r), "'", host, "'");
285:
286: goto error_free_socket;
287: }
288:
289: memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen);
290:
291: freeaddrinfo(res);
292: }
293: srv_socket->addr.ipv6.sin6_port = htons(port);
294: addr_len = sizeof(struct sockaddr_in6);
295: break;
296: #endif
297: case AF_INET:
298: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in));
299: srv_socket->addr.ipv4.sin_family = AF_INET;
300: if (host == NULL) {
301: srv_socket->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
302: } else {
303: struct hostent *he;
304: if (NULL == (he = gethostbyname(host))) {
305: log_error_write(srv, __FILE__, __LINE__,
306: "sds", "gethostbyname failed: ",
307: h_errno, host);
308: goto error_free_socket;
309: }
310:
311: if (he->h_addrtype != AF_INET) {
312: log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
313: goto error_free_socket;
314: }
315:
316: if (he->h_length != sizeof(struct in_addr)) {
317: log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
318: goto error_free_socket;
319: }
320:
321: memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
322: }
323: srv_socket->addr.ipv4.sin_port = htons(port);
324:
325: addr_len = sizeof(struct sockaddr_in);
326:
327: break;
328: case AF_UNIX:
329: srv_socket->addr.un.sun_family = AF_UNIX;
330: strcpy(srv_socket->addr.un.sun_path, host);
331:
332: #ifdef SUN_LEN
333: addr_len = SUN_LEN(&srv_socket->addr.un);
334: #else
335: /* stevens says: */
336: addr_len = strlen(host) + 1 + sizeof(srv_socket->addr.un.sun_family);
337: #endif
338:
339: /* check if the socket exists and try to connect to it. */
340: if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
341: close(fd);
342:
343: log_error_write(srv, __FILE__, __LINE__, "ss",
344: "server socket is still in use:",
345: host);
346:
347:
348: goto error_free_socket;
349: }
350:
351: /* connect failed */
352: switch(errno) {
353: case ECONNREFUSED:
354: unlink(host);
355: break;
356: case ENOENT:
357: break;
358: default:
359: log_error_write(srv, __FILE__, __LINE__, "sds",
360: "testing socket failed:",
361: host, strerror(errno));
362:
363: goto error_free_socket;
364: }
365:
366: break;
367: default:
368: goto error_free_socket;
369: }
370:
371: if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
372: switch(srv_socket->addr.plain.sa_family) {
373: case AF_UNIX:
374: log_error_write(srv, __FILE__, __LINE__, "sds",
375: "can't bind to socket:",
376: host, strerror(errno));
377: break;
378: default:
379: log_error_write(srv, __FILE__, __LINE__, "ssds",
380: "can't bind to port:",
381: host, port, strerror(errno));
382: break;
383: }
384: goto error_free_socket;
385: }
386:
387: if (-1 == listen(srv_socket->fd, 128 * 8)) {
388: log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
389: goto error_free_socket;
390: }
391:
392: if (s->ssl_enabled) {
393: #ifdef USE_OPENSSL
394: if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) {
395: log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
396: goto error_free_socket;
397: }
398: #else
399:
400: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
401: "ssl requested but openssl support is not compiled in");
402:
403: goto error_free_socket;
404: #endif
405: #ifdef TCP_DEFER_ACCEPT
406: } else if (s->defer_accept) {
407: int v = s->defer_accept;
408: if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) {
409: log_error_write(srv, __FILE__, __LINE__, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno));
410: }
411: #endif
412: } else {
413: #ifdef SO_ACCEPTFILTER
414: /* FreeBSD accf_http filter */
415: struct accept_filter_arg afa;
416: memset(&afa, 0, sizeof(afa));
417: strcpy(afa.af_name, "httpready");
418: if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
419: if (errno != ENOENT) {
420: log_error_write(srv, __FILE__, __LINE__, "ss", "can't set accept-filter 'httpready': ", strerror(errno));
421: }
422: }
423: #endif
424: }
425:
426: srv_socket->is_ssl = s->ssl_enabled;
427:
428: if (srv->srv_sockets.size == 0) {
429: srv->srv_sockets.size = 4;
430: srv->srv_sockets.used = 0;
431: srv->srv_sockets.ptr = malloc(srv->srv_sockets.size * sizeof(server_socket));
432: } else if (srv->srv_sockets.used == srv->srv_sockets.size) {
433: srv->srv_sockets.size += 4;
434: srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket));
435: }
436:
437: srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
438:
439: buffer_free(b);
440:
441: return 0;
442:
443: error_free_socket:
444: if (srv_socket->fd != -1) {
445: /* check if server fd are already registered */
446: if (srv_socket->fde_ndx != -1) {
447: fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
448: fdevent_unregister(srv->ev, srv_socket->fd);
449: }
450:
451: close(srv_socket->fd);
452: }
453: buffer_free(srv_socket->srv_token);
454: free(srv_socket);
455:
456: buffer_free(b);
457:
458: return -1;
459: }
460:
461: int network_close(server *srv) {
462: size_t i;
463: for (i = 0; i < srv->srv_sockets.used; i++) {
464: server_socket *srv_socket = srv->srv_sockets.ptr[i];
465:
466: if (srv_socket->fd != -1) {
467: /* check if server fd are already registered */
468: if (srv_socket->fde_ndx != -1) {
469: fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
470: fdevent_unregister(srv->ev, srv_socket->fd);
471: }
472:
473: close(srv_socket->fd);
474: }
475:
476: buffer_free(srv_socket->srv_token);
477:
478: free(srv_socket);
479: }
480:
481: free(srv->srv_sockets.ptr);
482:
483: return 0;
484: }
485:
486: typedef enum {
487: NETWORK_BACKEND_UNSET,
488: NETWORK_BACKEND_WRITE,
489: NETWORK_BACKEND_WRITEV,
490: NETWORK_BACKEND_LINUX_SENDFILE,
491: NETWORK_BACKEND_FREEBSD_SENDFILE,
492: NETWORK_BACKEND_SOLARIS_SENDFILEV
493: } network_backend_t;
494:
495: int network_init(server *srv) {
496: buffer *b;
497: size_t i;
498: network_backend_t backend;
499:
500: #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
501: #ifndef OPENSSL_NO_ECDH
502: EC_KEY *ecdh;
503: int nid;
504: #endif
505: #endif
506:
507: #ifdef USE_OPENSSL
508: # ifndef OPENSSL_NO_DH
509: DH *dh;
510: # endif
511: BIO *bio;
512:
513: /* 1024-bit MODP Group with 160-bit prime order subgroup (RFC5114)
514: * -----BEGIN DH PARAMETERS-----
515: * MIIBDAKBgQCxC4+WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y
516: * mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O/rMvdfZDEvXCYSI6cIZpzck7/1vrlZEc4
517: * +qMaT/VbzMChUa9fDci0vUW/N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV
518: * w/00EmdlpELvuZkF+BBN0lisUH/WQGz/FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0
519: * sBuIal6RVH+eJ0n01/vX07mpLuGQnQ0iY/gKdqaiTAh6CR9THb8KAWm2oorWYqTR
520: * jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5QICAKA=
521: * -----END DH PARAMETERS-----
522: */
523:
524: static const unsigned char dh1024_p[]={
525: 0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E,
526: 0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6,
527: 0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86,
528: 0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0,
529: 0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C,
530: 0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70,
531: 0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA,
532: 0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0,
533: 0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF,
534: 0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08,
535: 0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71,
536: };
537:
538: static const unsigned char dh1024_g[]={
539: 0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42,
540: 0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F,
541: 0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E,
542: 0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13,
543: 0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F,
544: 0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1,
545: 0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08,
546: 0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A,
547: 0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59,
548: 0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24,
549: 0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5,
550: };
551: #endif
552:
553: struct nb_map {
554: network_backend_t nb;
555: const char *name;
556: } network_backends[] = {
557: /* lowest id wins */
558: #if defined USE_LINUX_SENDFILE
559: { NETWORK_BACKEND_LINUX_SENDFILE, "linux-sendfile" },
560: #endif
561: #if defined USE_FREEBSD_SENDFILE
562: { NETWORK_BACKEND_FREEBSD_SENDFILE, "freebsd-sendfile" },
563: #endif
564: #if defined USE_SOLARIS_SENDFILEV
565: { NETWORK_BACKEND_SOLARIS_SENDFILEV, "solaris-sendfilev" },
566: #endif
567: #if defined USE_WRITEV
568: { NETWORK_BACKEND_WRITEV, "writev" },
569: #endif
570: { NETWORK_BACKEND_WRITE, "write" },
571: { NETWORK_BACKEND_UNSET, NULL }
572: };
573:
574: #ifdef USE_OPENSSL
575: /* load SSL certificates */
576: for (i = 0; i < srv->config_context->used; i++) {
577: specific_config *s = srv->config_storage[i];
578: #ifndef SSL_OP_NO_COMPRESSION
579: # define SSL_OP_NO_COMPRESSION 0
580: #endif
581: long ssloptions =
582: SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_COMPRESSION;
583:
584: if (buffer_is_empty(s->ssl_pemfile)) continue;
585:
586: #ifdef OPENSSL_NO_TLSEXT
587: {
588: data_config *dc = (data_config *)srv->config_context->data[i];
589: if (COMP_HTTP_HOST == dc->comp) {
590: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
591: "can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions");
592: return -1;
593: }
594: }
595: #endif
596:
597: if (srv->ssl_is_init == 0) {
598: SSL_load_error_strings();
599: SSL_library_init();
600: OpenSSL_add_all_algorithms();
601: srv->ssl_is_init = 1;
602:
603: if (0 == RAND_status()) {
604: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
605: "not enough entropy in the pool");
606: return -1;
607: }
608: }
609:
610: if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
611: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
612: ERR_error_string(ERR_get_error(), NULL));
613: return -1;
614: }
615:
616: if (s->ssl_empty_fragments) {
617: #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
618: ssloptions &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
619: #else
620: ssloptions &= ~0x00000800L; /* hardcode constant */
621: log_error_write(srv, __FILE__, __LINE__, "ss", "WARNING: SSL:",
622: "'insert empty fragments' not supported by the openssl version used to compile lighttpd with");
623: #endif
624: }
625:
626: SSL_CTX_set_options(s->ssl_ctx, ssloptions);
627: SSL_CTX_set_info_callback(s->ssl_ctx, ssl_info_callback);
628:
629: if (!s->ssl_use_sslv2) {
630: /* disable SSLv2 */
631: if (!(SSL_OP_NO_SSLv2 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2))) {
632: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
633: ERR_error_string(ERR_get_error(), NULL));
634: return -1;
635: }
636: }
637:
638: if (!s->ssl_use_sslv3) {
639: /* disable SSLv3 */
640: if (!(SSL_OP_NO_SSLv3 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv3))) {
641: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
642: ERR_error_string(ERR_get_error(), NULL));
643: return -1;
644: }
645: }
646:
647: if (!buffer_is_empty(s->ssl_cipher_list)) {
648: /* Disable support for low encryption ciphers */
649: if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
650: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
651: ERR_error_string(ERR_get_error(), NULL));
652: return -1;
653: }
654:
655: if (s->ssl_honor_cipher_order) {
656: SSL_CTX_set_options(s->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
657: }
658: }
659:
660: #ifndef OPENSSL_NO_DH
661: /* Support for Diffie-Hellman key exchange */
662: if (!buffer_is_empty(s->ssl_dh_file)) {
663: /* DH parameters from file */
664: bio = BIO_new_file((char *) s->ssl_dh_file->ptr, "r");
665: if (bio == NULL) {
666: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: Unable to open file", s->ssl_dh_file->ptr);
667: return -1;
668: }
669: dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
670: BIO_free(bio);
671: if (dh == NULL) {
672: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: PEM_read_bio_DHparams failed", s->ssl_dh_file->ptr);
673: return -1;
674: }
675: } else {
676: /* Default DH parameters from RFC5114 */
677: dh = DH_new();
678: if (dh == NULL) {
679: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: DH_new () failed");
680: return -1;
681: }
682: dh->p = BN_bin2bn(dh1024_p,sizeof(dh1024_p), NULL);
683: dh->g = BN_bin2bn(dh1024_g,sizeof(dh1024_g), NULL);
684: dh->length = 160;
685: if ((dh->p == NULL) || (dh->g == NULL)) {
686: DH_free(dh);
687: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: BN_bin2bn () failed");
688: return -1;
689: }
690: }
691: SSL_CTX_set_tmp_dh(s->ssl_ctx,dh);
692: SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_DH_USE);
693: DH_free(dh);
694: #else
695: if (!buffer_is_empty(s->ssl_dh_file)) {
696: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: openssl compiled without DH support, can't load parameters from", s->ssl_dh_file->ptr);
697: }
698: #endif
699:
700: #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
701: #ifndef OPENSSL_NO_ECDH
702: /* Support for Elliptic-Curve Diffie-Hellman key exchange */
703: if (!buffer_is_empty(s->ssl_ec_curve)) {
704: /* OpenSSL only supports the "named curves" from RFC 4492, section 5.1.1. */
705: nid = OBJ_sn2nid((char *) s->ssl_ec_curve->ptr);
706: if (nid == 0) {
707: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: Unknown curve name", s->ssl_ec_curve->ptr);
708: return -1;
709: }
710: } else {
711: /* Default curve */
712: nid = OBJ_sn2nid("prime256v1");
713: }
714: ecdh = EC_KEY_new_by_curve_name(nid);
715: if (ecdh == NULL) {
716: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: Unable to create curve", s->ssl_ec_curve->ptr);
717: return -1;
718: }
719: SSL_CTX_set_tmp_ecdh(s->ssl_ctx,ecdh);
720: SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_ECDH_USE);
721: EC_KEY_free(ecdh);
722: #endif
723: #endif
724:
725: if (!buffer_is_empty(s->ssl_ca_file)) {
726: if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
727: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
728: ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
729: return -1;
730: }
731: if (s->ssl_verifyclient) {
732: STACK_OF(X509_NAME) *certs = SSL_load_client_CA_file(s->ssl_ca_file->ptr);
733: if (!certs) {
734: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
735: ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
736: }
737: if (SSL_CTX_set_session_id_context(s->ssl_ctx, (void*) &srv, sizeof(srv)) != 1) {
738: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
739: ERR_error_string(ERR_get_error(), NULL));
740: return -1;
741: }
742: SSL_CTX_set_client_CA_list(s->ssl_ctx, certs);
743: SSL_CTX_set_verify(
744: s->ssl_ctx,
745: SSL_VERIFY_PEER | (s->ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
746: NULL
747: );
748: SSL_CTX_set_verify_depth(s->ssl_ctx, s->ssl_verifyclient_depth);
749: }
750: } else if (s->ssl_verifyclient) {
751: log_error_write(
752: srv, __FILE__, __LINE__, "s",
753: "SSL: You specified ssl.verifyclient.activate but no ca_file"
754: );
755: }
756:
757: if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
758: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
759: ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
760: return -1;
761: }
762:
763: if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
764: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
765: ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
766: return -1;
767: }
768:
769: if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
770: log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
771: "Private key does not match the certificate public key, reason:",
772: ERR_error_string(ERR_get_error(), NULL),
773: s->ssl_pemfile);
774: return -1;
775: }
776: SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1);
777: SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
778:
779: # ifndef OPENSSL_NO_TLSEXT
780: if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) ||
781: !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) {
782: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
783: "failed to initialize TLS servername callback, openssl library does not support TLS servername extension");
784: return -1;
785: }
786: # endif
787: }
788: #endif
789:
790: b = buffer_init();
791:
792: buffer_copy_string_buffer(b, srv->srvconf.bindhost);
793: buffer_append_string_len(b, CONST_STR_LEN(":"));
794: buffer_append_long(b, srv->srvconf.port);
795:
796: if (0 != network_server_init(srv, b, srv->config_storage[0])) {
797: return -1;
798: }
799: buffer_free(b);
800:
801: #ifdef USE_OPENSSL
802: srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
803: #endif
804:
805: /* get a usefull default */
806: backend = network_backends[0].nb;
807:
808: /* match name against known types */
809: if (!buffer_is_empty(srv->srvconf.network_backend)) {
810: for (i = 0; network_backends[i].name; i++) {
811: /**/
812: if (buffer_is_equal_string(srv->srvconf.network_backend, network_backends[i].name, strlen(network_backends[i].name))) {
813: backend = network_backends[i].nb;
814: break;
815: }
816: }
817: if (NULL == network_backends[i].name) {
818: /* we don't know it */
819:
820: log_error_write(srv, __FILE__, __LINE__, "sb",
821: "server.network-backend has a unknown value:",
822: srv->srvconf.network_backend);
823:
824: return -1;
825: }
826: }
827:
828: switch(backend) {
829: case NETWORK_BACKEND_WRITE:
830: srv->network_backend_write = network_write_chunkqueue_write;
831: break;
832: #ifdef USE_WRITEV
833: case NETWORK_BACKEND_WRITEV:
834: srv->network_backend_write = network_write_chunkqueue_writev;
835: break;
836: #endif
837: #ifdef USE_LINUX_SENDFILE
838: case NETWORK_BACKEND_LINUX_SENDFILE:
839: srv->network_backend_write = network_write_chunkqueue_linuxsendfile;
840: break;
841: #endif
842: #ifdef USE_FREEBSD_SENDFILE
843: case NETWORK_BACKEND_FREEBSD_SENDFILE:
844: srv->network_backend_write = network_write_chunkqueue_freebsdsendfile;
845: break;
846: #endif
847: #ifdef USE_SOLARIS_SENDFILEV
848: case NETWORK_BACKEND_SOLARIS_SENDFILEV:
849: srv->network_backend_write = network_write_chunkqueue_solarissendfilev;
850: break;
851: #endif
852: default:
853: return -1;
854: }
855:
856: /* check for $SERVER["socket"] */
857: for (i = 1; i < srv->config_context->used; i++) {
858: data_config *dc = (data_config *)srv->config_context->data[i];
859: specific_config *s = srv->config_storage[i];
860: size_t j;
861:
862: /* not our stage */
863: if (COMP_SERVER_SOCKET != dc->comp) continue;
864:
865: if (dc->cond != CONFIG_COND_EQ) continue;
866:
867: /* check if we already know this socket,
868: * if yes, don't init it */
869: for (j = 0; j < srv->srv_sockets.used; j++) {
870: if (buffer_is_equal(srv->srv_sockets.ptr[j]->srv_token, dc->string)) {
871: break;
872: }
873: }
874:
875: if (j == srv->srv_sockets.used) {
876: if (0 != network_server_init(srv, dc->string, s)) return -1;
877: }
878: }
879:
880: return 0;
881: }
882:
883: int network_register_fdevents(server *srv) {
884: size_t i;
885:
886: if (-1 == fdevent_reset(srv->ev)) {
887: return -1;
888: }
889:
890: /* register fdevents after reset */
891: for (i = 0; i < srv->srv_sockets.used; i++) {
892: server_socket *srv_socket = srv->srv_sockets.ptr[i];
893:
894: fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
895: fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
896: }
897: return 0;
898: }
899:
900: int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
901: int ret = -1;
902: off_t written = 0;
903: #ifdef TCP_CORK
904: int corked = 0;
905: #endif
906: server_socket *srv_socket = con->srv_socket;
907:
908: if (con->conf.global_kbytes_per_second) {
909: off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr);
910: if (limit <= 0) {
911: /* we reached the global traffic limit */
912:
913: con->traffic_limit_reached = 1;
914: joblist_append(srv, con);
915:
916: return 1;
917: } else {
918: if (max_bytes > limit) max_bytes = limit;
919: }
920: }
921:
922: if (con->conf.kbytes_per_second) {
923: off_t limit = con->conf.kbytes_per_second * 1024 - con->bytes_written_cur_second;
924: if (limit <= 0) {
925: /* we reached the traffic limit */
926:
927: con->traffic_limit_reached = 1;
928: joblist_append(srv, con);
929:
930: return 1;
931: } else {
932: if (max_bytes > limit) max_bytes = limit;
933: }
934: }
935:
936: written = cq->bytes_out;
937:
938: #ifdef TCP_CORK
939: /* Linux: put a cork into the socket as we want to combine the write() calls
940: * but only if we really have multiple chunks
941: */
942: if (cq->first && cq->first->next) {
943: corked = 1;
944: setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
945: }
946: #endif
947:
948: if (srv_socket->is_ssl) {
949: #ifdef USE_OPENSSL
950: ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq, max_bytes);
951: #endif
952: } else {
953: ret = srv->network_backend_write(srv, con, con->fd, cq, max_bytes);
954: }
955:
956: if (ret >= 0) {
957: chunkqueue_remove_finished_chunks(cq);
958: ret = chunkqueue_is_empty(cq) ? 0 : 1;
959: }
960:
961: #ifdef TCP_CORK
962: if (corked) {
963: corked = 0;
964: setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
965: }
966: #endif
967:
968: written = cq->bytes_out - written;
969: con->bytes_written += written;
970: con->bytes_written_cur_second += written;
971:
972: *(con->conf.global_bytes_per_second_cnt_ptr) += written;
973:
974: return ret;
975: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>