Annotation of embedaddon/lighttpd/src/network.c, revision 1.1.1.2.2.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:
1.1.1.2 misho 115: if (NULL == con->conf.ssl_pemfile_x509 || NULL == con->conf.ssl_pemfile_pkey) {
116: /* x509/pkey available <=> pemfile was set <=> pemfile got patched: so this should never happen, unless you nest $SERVER["socket"] */
1.1 misho 117: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
1.1.1.2 misho 118: "no certificate/private key for TLS server name", con->tlsext_server_name);
1.1 misho 119: return SSL_TLSEXT_ERR_ALERT_FATAL;
120: }
121:
1.1.1.2 misho 122: /* first set certificate! setting private key checks whether certificate matches it */
123: if (!SSL_use_certificate(ssl, con->conf.ssl_pemfile_x509)) {
124: log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
125: "failed to set certificate for TLS server name", con->tlsext_server_name,
126: ERR_error_string(ERR_get_error(), NULL));
127: return SSL_TLSEXT_ERR_ALERT_FATAL;
128: }
129:
130: if (!SSL_use_PrivateKey(ssl, con->conf.ssl_pemfile_pkey)) {
131: log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
132: "failed to set private key for TLS server name", con->tlsext_server_name,
133: ERR_error_string(ERR_get_error(), NULL));
1.1 misho 134: return SSL_TLSEXT_ERR_ALERT_FATAL;
135: }
136:
1.1.1.2 misho 137: if (con->conf.ssl_verifyclient) {
138: if (NULL == con->conf.ssl_ca_file_cert_names) {
139: log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
140: "can't verify client without ssl.ca-file for TLS server name", con->tlsext_server_name,
141: ERR_error_string(ERR_get_error(), NULL));
142: return SSL_TLSEXT_ERR_ALERT_FATAL;
143: }
144:
145: SSL_set_client_CA_list(ssl, SSL_dup_CA_list(con->conf.ssl_ca_file_cert_names));
146: /* forcing verification here is really not that useful - a client could just connect without SNI */
147: SSL_set_verify(
148: ssl,
149: SSL_VERIFY_PEER | (con->conf.ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
150: NULL
151: );
152: SSL_set_verify_depth(ssl, con->conf.ssl_verifyclient_depth);
153: }
154:
1.1 misho 155: return SSL_TLSEXT_ERR_OK;
156: }
157: #endif
158:
159: static int network_server_init(server *srv, buffer *host_token, specific_config *s) {
160: int val;
161: socklen_t addr_len;
162: server_socket *srv_socket;
163: char *sp;
164: unsigned int port = 0;
165: const char *host;
166: buffer *b;
167: int is_unix_domain_socket = 0;
168: int fd;
169:
170: #ifdef __WIN32
171: WORD wVersionRequested;
172: WSADATA wsaData;
173: int err;
174:
175: wVersionRequested = MAKEWORD( 2, 2 );
176:
177: err = WSAStartup( wVersionRequested, &wsaData );
178: if ( err != 0 ) {
179: /* Tell the user that we could not find a usable */
180: /* WinSock DLL. */
181: return -1;
182: }
183: #endif
184:
185: srv_socket = calloc(1, sizeof(*srv_socket));
186: srv_socket->fd = -1;
187: srv_socket->fde_ndx = -1;
188:
189: srv_socket->srv_token = buffer_init();
190: buffer_copy_string_buffer(srv_socket->srv_token, host_token);
191:
192: b = buffer_init();
193: buffer_copy_string_buffer(b, host_token);
194:
195: /* ipv4:port
196: * [ipv6]:port
197: */
198: if (NULL == (sp = strrchr(b->ptr, ':'))) {
199: log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b);
200:
201: goto error_free_socket;
202: }
203:
204: host = b->ptr;
205:
206: /* check for [ and ] */
207: if (b->ptr[0] == '[' && *(sp-1) == ']') {
208: *(sp-1) = '\0';
209: host++;
210:
211: s->use_ipv6 = 1;
212: }
213:
214: *(sp++) = '\0';
215:
216: port = strtol(sp, NULL, 10);
217:
218: if (host[0] == '/') {
219: /* host is a unix-domain-socket */
220: is_unix_domain_socket = 1;
221: } else if (port == 0 || port > 65535) {
222: log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port);
223:
224: goto error_free_socket;
225: }
226:
227: if (*host == '\0') host = NULL;
228:
229: if (is_unix_domain_socket) {
230: #ifdef HAVE_SYS_UN_H
231:
232: srv_socket->addr.plain.sa_family = AF_UNIX;
233:
234: if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
235: log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
236: goto error_free_socket;
237: }
238: #else
239: log_error_write(srv, __FILE__, __LINE__, "s",
240: "ERROR: Unix Domain sockets are not supported.");
241: goto error_free_socket;
242: #endif
243: }
244:
245: #ifdef HAVE_IPV6
246: if (s->use_ipv6) {
247: srv_socket->addr.plain.sa_family = AF_INET6;
248:
249: if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
250: log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
251: goto error_free_socket;
252: }
253: }
254: #endif
255:
256: if (srv_socket->fd == -1) {
257: srv_socket->addr.plain.sa_family = AF_INET;
258: if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
259: log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
260: goto error_free_socket;
261: }
262: }
263:
264: /* set FD_CLOEXEC now, fdevent_fcntl_set is called later; needed for pipe-logger forks */
1.1.1.2 misho 265: fd_close_on_exec(srv_socket->fd);
1.1 misho 266:
267: /* */
268: srv->cur_fds = srv_socket->fd;
269:
270: val = 1;
271: if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
272: log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(SO_REUSEADDR) failed:", strerror(errno));
273: goto error_free_socket;
274: }
1.1.1.2.2.1! misho 275: if(srv_socket->addr.plain.sa_family == AF_INET || srv_socket->addr.plain.sa_family == AF_INET6 ) {
! 276: if (setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) < 0) {
! 277: log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno));
! 278: goto error_free_socket;
! 279: }
! 280: }
1.1 misho 281:
282: switch(srv_socket->addr.plain.sa_family) {
283: #ifdef HAVE_IPV6
284: case AF_INET6:
285: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in6));
286: srv_socket->addr.ipv6.sin6_family = AF_INET6;
287: if (host == NULL) {
288: srv_socket->addr.ipv6.sin6_addr = in6addr_any;
289: 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");
290: } else {
291: struct addrinfo hints, *res;
292: int r;
293:
294: if (s->set_v6only) {
295: val = 1;
296: if (-1 == setsockopt(srv_socket->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) {
297: log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(IPV6_V6ONLY) failed:", strerror(errno));
298: goto error_free_socket;
299: }
300: } else {
301: 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");
302: }
303:
304: memset(&hints, 0, sizeof(hints));
305:
306: hints.ai_family = AF_INET6;
307: hints.ai_socktype = SOCK_STREAM;
308: hints.ai_protocol = IPPROTO_TCP;
309:
310: if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
311: log_error_write(srv, __FILE__, __LINE__,
312: "sssss", "getaddrinfo failed: ",
313: gai_strerror(r), "'", host, "'");
314:
315: goto error_free_socket;
316: }
317:
318: memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen);
319:
320: freeaddrinfo(res);
321: }
322: srv_socket->addr.ipv6.sin6_port = htons(port);
323: addr_len = sizeof(struct sockaddr_in6);
324: break;
325: #endif
326: case AF_INET:
327: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in));
328: srv_socket->addr.ipv4.sin_family = AF_INET;
329: if (host == NULL) {
330: srv_socket->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
331: } else {
332: struct hostent *he;
333: if (NULL == (he = gethostbyname(host))) {
334: log_error_write(srv, __FILE__, __LINE__,
335: "sds", "gethostbyname failed: ",
336: h_errno, host);
337: goto error_free_socket;
338: }
339:
340: if (he->h_addrtype != AF_INET) {
341: log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
342: goto error_free_socket;
343: }
344:
345: if (he->h_length != sizeof(struct in_addr)) {
346: log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
347: goto error_free_socket;
348: }
349:
350: memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
351: }
352: srv_socket->addr.ipv4.sin_port = htons(port);
353:
354: addr_len = sizeof(struct sockaddr_in);
355:
356: break;
357: case AF_UNIX:
1.1.1.2 misho 358: {
359: size_t hostlen = strlen(host) + 1;
360: if (hostlen > sizeof(srv_socket->addr.un.sun_path)) {
361: log_error_write(srv, __FILE__, __LINE__, "sS", "unix socket filename too long:", host);
362: goto error_free_socket;
363: }
364: memcpy(srv_socket->addr.un.sun_path, host, hostlen);
365: }
1.1 misho 366: srv_socket->addr.un.sun_family = AF_UNIX;
367:
368: #ifdef SUN_LEN
369: addr_len = SUN_LEN(&srv_socket->addr.un);
370: #else
371: /* stevens says: */
1.1.1.2 misho 372: addr_len = hostlen + sizeof(srv_socket->addr.un.sun_family);
1.1 misho 373: #endif
374:
375: /* check if the socket exists and try to connect to it. */
376: if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
377: close(fd);
378:
379: log_error_write(srv, __FILE__, __LINE__, "ss",
380: "server socket is still in use:",
381: host);
382:
383:
384: goto error_free_socket;
385: }
386:
387: /* connect failed */
388: switch(errno) {
389: case ECONNREFUSED:
390: unlink(host);
391: break;
392: case ENOENT:
393: break;
394: default:
395: log_error_write(srv, __FILE__, __LINE__, "sds",
396: "testing socket failed:",
397: host, strerror(errno));
398:
399: goto error_free_socket;
400: }
401:
402: break;
403: default:
404: goto error_free_socket;
405: }
406:
407: if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
408: switch(srv_socket->addr.plain.sa_family) {
409: case AF_UNIX:
410: log_error_write(srv, __FILE__, __LINE__, "sds",
411: "can't bind to socket:",
412: host, strerror(errno));
413: break;
414: default:
415: log_error_write(srv, __FILE__, __LINE__, "ssds",
416: "can't bind to port:",
417: host, port, strerror(errno));
418: break;
419: }
420: goto error_free_socket;
421: }
422:
423: if (-1 == listen(srv_socket->fd, 128 * 8)) {
424: log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
425: goto error_free_socket;
426: }
427:
428: if (s->ssl_enabled) {
429: #ifdef USE_OPENSSL
430: if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) {
431: log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
432: goto error_free_socket;
433: }
434: #else
435:
436: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
437: "ssl requested but openssl support is not compiled in");
438:
439: goto error_free_socket;
440: #endif
441: #ifdef TCP_DEFER_ACCEPT
442: } else if (s->defer_accept) {
443: int v = s->defer_accept;
444: if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) {
445: log_error_write(srv, __FILE__, __LINE__, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno));
446: }
447: #endif
448: } else {
449: #ifdef SO_ACCEPTFILTER
450: /* FreeBSD accf_http filter */
451: struct accept_filter_arg afa;
452: memset(&afa, 0, sizeof(afa));
453: strcpy(afa.af_name, "httpready");
454: if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
455: if (errno != ENOENT) {
456: log_error_write(srv, __FILE__, __LINE__, "ss", "can't set accept-filter 'httpready': ", strerror(errno));
457: }
458: }
459: #endif
460: }
461:
462: srv_socket->is_ssl = s->ssl_enabled;
463:
464: if (srv->srv_sockets.size == 0) {
465: srv->srv_sockets.size = 4;
466: srv->srv_sockets.used = 0;
1.1.1.2 misho 467: srv->srv_sockets.ptr = malloc(srv->srv_sockets.size * sizeof(server_socket*));
1.1 misho 468: } else if (srv->srv_sockets.used == srv->srv_sockets.size) {
469: srv->srv_sockets.size += 4;
1.1.1.2 misho 470: srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket*));
1.1 misho 471: }
472:
473: srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
474:
475: buffer_free(b);
476:
477: return 0;
478:
479: error_free_socket:
480: if (srv_socket->fd != -1) {
481: /* check if server fd are already registered */
482: if (srv_socket->fde_ndx != -1) {
483: fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
484: fdevent_unregister(srv->ev, srv_socket->fd);
485: }
486:
487: close(srv_socket->fd);
488: }
489: buffer_free(srv_socket->srv_token);
490: free(srv_socket);
491:
492: buffer_free(b);
493:
494: return -1;
495: }
496:
497: int network_close(server *srv) {
498: size_t i;
499: for (i = 0; i < srv->srv_sockets.used; i++) {
500: server_socket *srv_socket = srv->srv_sockets.ptr[i];
501:
502: if (srv_socket->fd != -1) {
503: /* check if server fd are already registered */
504: if (srv_socket->fde_ndx != -1) {
505: fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
506: fdevent_unregister(srv->ev, srv_socket->fd);
507: }
508:
509: close(srv_socket->fd);
510: }
511:
512: buffer_free(srv_socket->srv_token);
513:
514: free(srv_socket);
515: }
516:
517: free(srv->srv_sockets.ptr);
518:
519: return 0;
520: }
521:
522: typedef enum {
523: NETWORK_BACKEND_UNSET,
524: NETWORK_BACKEND_WRITE,
525: NETWORK_BACKEND_WRITEV,
526: NETWORK_BACKEND_LINUX_SENDFILE,
527: NETWORK_BACKEND_FREEBSD_SENDFILE,
528: NETWORK_BACKEND_SOLARIS_SENDFILEV
529: } network_backend_t;
530:
1.1.1.2 misho 531: #ifdef USE_OPENSSL
532: static X509* x509_load_pem_file(server *srv, const char *file) {
533: BIO *in;
534: X509 *x = NULL;
535:
536: in = BIO_new(BIO_s_file());
537: if (NULL == in) {
538: log_error_write(srv, __FILE__, __LINE__, "S", "SSL: BIO_new(BIO_s_file()) failed");
539: goto error;
540: }
541:
542: if (BIO_read_filename(in,file) <= 0) {
543: log_error_write(srv, __FILE__, __LINE__, "SSS", "SSL: BIO_read_filename('", file,"') failed");
544: goto error;
545: }
546: x = PEM_read_bio_X509(in, NULL, NULL, NULL);
547:
548: if (NULL == x) {
549: log_error_write(srv, __FILE__, __LINE__, "SSS", "SSL: couldn't read X509 certificate from '", file,"'");
550: goto error;
551: }
552:
553: BIO_free(in);
554: return x;
555:
556: error:
557: if (NULL != in) BIO_free(in);
558: return NULL;
559: }
560:
561: static EVP_PKEY* evp_pkey_load_pem_file(server *srv, const char *file) {
562: BIO *in;
563: EVP_PKEY *x = NULL;
564:
565: in=BIO_new(BIO_s_file());
566: if (NULL == in) {
567: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: BIO_new(BIO_s_file()) failed");
568: goto error;
569: }
570:
571: if (BIO_read_filename(in,file) <= 0) {
572: log_error_write(srv, __FILE__, __LINE__, "SSS", "SSL: BIO_read_filename('", file,"') failed");
573: goto error;
574: }
575: x = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
576:
577: if (NULL == x) {
578: log_error_write(srv, __FILE__, __LINE__, "SSS", "SSL: couldn't read private key from '", file,"'");
579: goto error;
580: }
581:
582: BIO_free(in);
583: return x;
584:
585: error:
586: if (NULL != in) BIO_free(in);
587: return NULL;
588: }
589:
590: static int network_openssl_load_pemfile(server *srv, size_t ndx) {
591: specific_config *s = srv->config_storage[ndx];
592:
593: #ifdef OPENSSL_NO_TLSEXT
594: {
595: data_config *dc = (data_config *)srv->config_context->data[ndx];
596: if ((ndx > 0 && (COMP_SERVER_SOCKET != dc->comp || dc->cond != CONFIG_COND_EQ))
597: || !s->ssl_enabled) {
598: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
599: "ssl.pemfile only works in SSL socket binding context as openssl version does not support TLS extensions");
600: return -1;
601: }
602: }
603: #endif
604:
605: if (NULL == (s->ssl_pemfile_x509 = x509_load_pem_file(srv, s->ssl_pemfile->ptr))) return -1;
606: if (NULL == (s->ssl_pemfile_pkey = evp_pkey_load_pem_file(srv, s->ssl_pemfile->ptr))) return -1;
607:
608: if (!X509_check_private_key(s->ssl_pemfile_x509, s->ssl_pemfile_pkey)) {
609: log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
610: "Private key does not match the certificate public key, reason:",
611: ERR_error_string(ERR_get_error(), NULL),
612: s->ssl_pemfile);
613: return -1;
614: }
615:
616: return 0;
617: }
618: #endif
619:
1.1 misho 620: int network_init(server *srv) {
621: buffer *b;
1.1.1.2 misho 622: size_t i, j;
1.1 misho 623: network_backend_t backend;
624:
625: #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
626: #ifndef OPENSSL_NO_ECDH
627: EC_KEY *ecdh;
628: int nid;
629: #endif
630: #endif
631:
632: #ifdef USE_OPENSSL
633: # ifndef OPENSSL_NO_DH
634: DH *dh;
635: # endif
636: BIO *bio;
637:
638: /* 1024-bit MODP Group with 160-bit prime order subgroup (RFC5114)
639: * -----BEGIN DH PARAMETERS-----
640: * MIIBDAKBgQCxC4+WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y
641: * mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O/rMvdfZDEvXCYSI6cIZpzck7/1vrlZEc4
642: * +qMaT/VbzMChUa9fDci0vUW/N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV
643: * w/00EmdlpELvuZkF+BBN0lisUH/WQGz/FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0
644: * sBuIal6RVH+eJ0n01/vX07mpLuGQnQ0iY/gKdqaiTAh6CR9THb8KAWm2oorWYqTR
645: * jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5QICAKA=
646: * -----END DH PARAMETERS-----
647: */
648:
649: static const unsigned char dh1024_p[]={
650: 0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E,
651: 0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6,
652: 0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86,
653: 0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0,
654: 0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C,
655: 0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70,
656: 0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA,
657: 0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0,
658: 0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF,
659: 0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08,
660: 0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71,
661: };
662:
663: static const unsigned char dh1024_g[]={
664: 0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42,
665: 0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F,
666: 0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E,
667: 0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13,
668: 0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F,
669: 0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1,
670: 0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08,
671: 0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A,
672: 0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59,
673: 0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24,
674: 0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5,
675: };
676: #endif
677:
678: struct nb_map {
679: network_backend_t nb;
680: const char *name;
681: } network_backends[] = {
682: /* lowest id wins */
683: #if defined USE_LINUX_SENDFILE
684: { NETWORK_BACKEND_LINUX_SENDFILE, "linux-sendfile" },
685: #endif
686: #if defined USE_FREEBSD_SENDFILE
687: { NETWORK_BACKEND_FREEBSD_SENDFILE, "freebsd-sendfile" },
688: #endif
689: #if defined USE_SOLARIS_SENDFILEV
690: { NETWORK_BACKEND_SOLARIS_SENDFILEV, "solaris-sendfilev" },
691: #endif
692: #if defined USE_WRITEV
693: { NETWORK_BACKEND_WRITEV, "writev" },
694: #endif
695: { NETWORK_BACKEND_WRITE, "write" },
696: { NETWORK_BACKEND_UNSET, NULL }
697: };
698:
699: #ifdef USE_OPENSSL
700: /* load SSL certificates */
701: for (i = 0; i < srv->config_context->used; i++) {
702: specific_config *s = srv->config_storage[i];
703: #ifndef SSL_OP_NO_COMPRESSION
704: # define SSL_OP_NO_COMPRESSION 0
705: #endif
706: long ssloptions =
707: SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_COMPRESSION;
708:
1.1.1.2 misho 709: if (buffer_is_empty(s->ssl_pemfile) && buffer_is_empty(s->ssl_ca_file)) continue;
1.1 misho 710:
711: if (srv->ssl_is_init == 0) {
712: SSL_load_error_strings();
713: SSL_library_init();
714: OpenSSL_add_all_algorithms();
715: srv->ssl_is_init = 1;
716:
717: if (0 == RAND_status()) {
718: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
719: "not enough entropy in the pool");
720: return -1;
721: }
722: }
723:
1.1.1.2 misho 724: if (!buffer_is_empty(s->ssl_pemfile)) {
725: #ifdef OPENSSL_NO_TLSEXT
726: data_config *dc = (data_config *)srv->config_context->data[i];
727: if (COMP_HTTP_HOST == dc->comp) {
728: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
729: "can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions");
730: return -1;
731: }
732: #endif
733: if (network_openssl_load_pemfile(srv, i)) return -1;
734: }
735:
736:
737: if (!buffer_is_empty(s->ssl_ca_file)) {
738: s->ssl_ca_file_cert_names = SSL_load_client_CA_file(s->ssl_ca_file->ptr);
739: if (NULL == s->ssl_ca_file_cert_names) {
740: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
741: ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
742: }
743: }
744:
745: if (buffer_is_empty(s->ssl_pemfile) || !s->ssl_enabled) continue;
746:
1.1 misho 747: if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
748: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
749: ERR_error_string(ERR_get_error(), NULL));
750: return -1;
751: }
752:
1.1.1.2 misho 753: /* completely useless identifier; required for client cert verification to work with sessions */
754: if (0 == SSL_CTX_set_session_id_context(s->ssl_ctx, (const unsigned char*) CONST_STR_LEN("lighttpd"))) {
755: log_error_write(srv, __FILE__, __LINE__, "ss:s", "SSL:",
756: "failed to set session context",
757: ERR_error_string(ERR_get_error(), NULL));
758: return -1;
759: }
760:
1.1 misho 761: if (s->ssl_empty_fragments) {
762: #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
763: ssloptions &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
764: #else
765: ssloptions &= ~0x00000800L; /* hardcode constant */
766: log_error_write(srv, __FILE__, __LINE__, "ss", "WARNING: SSL:",
767: "'insert empty fragments' not supported by the openssl version used to compile lighttpd with");
768: #endif
769: }
770:
771: SSL_CTX_set_options(s->ssl_ctx, ssloptions);
772: SSL_CTX_set_info_callback(s->ssl_ctx, ssl_info_callback);
773:
774: if (!s->ssl_use_sslv2) {
775: /* disable SSLv2 */
776: if (!(SSL_OP_NO_SSLv2 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2))) {
777: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
778: ERR_error_string(ERR_get_error(), NULL));
779: return -1;
780: }
781: }
782:
783: if (!s->ssl_use_sslv3) {
784: /* disable SSLv3 */
785: if (!(SSL_OP_NO_SSLv3 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv3))) {
786: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
787: ERR_error_string(ERR_get_error(), NULL));
788: return -1;
789: }
790: }
791:
792: if (!buffer_is_empty(s->ssl_cipher_list)) {
793: /* Disable support for low encryption ciphers */
794: if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
795: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
796: ERR_error_string(ERR_get_error(), NULL));
797: return -1;
798: }
799:
800: if (s->ssl_honor_cipher_order) {
801: SSL_CTX_set_options(s->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
802: }
803: }
804:
805: #ifndef OPENSSL_NO_DH
806: /* Support for Diffie-Hellman key exchange */
807: if (!buffer_is_empty(s->ssl_dh_file)) {
808: /* DH parameters from file */
809: bio = BIO_new_file((char *) s->ssl_dh_file->ptr, "r");
810: if (bio == NULL) {
811: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: Unable to open file", s->ssl_dh_file->ptr);
812: return -1;
813: }
814: dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
815: BIO_free(bio);
816: if (dh == NULL) {
817: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: PEM_read_bio_DHparams failed", s->ssl_dh_file->ptr);
818: return -1;
819: }
820: } else {
821: /* Default DH parameters from RFC5114 */
822: dh = DH_new();
823: if (dh == NULL) {
824: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: DH_new () failed");
825: return -1;
826: }
827: dh->p = BN_bin2bn(dh1024_p,sizeof(dh1024_p), NULL);
828: dh->g = BN_bin2bn(dh1024_g,sizeof(dh1024_g), NULL);
829: dh->length = 160;
830: if ((dh->p == NULL) || (dh->g == NULL)) {
831: DH_free(dh);
832: log_error_write(srv, __FILE__, __LINE__, "s", "SSL: BN_bin2bn () failed");
833: return -1;
834: }
835: }
836: SSL_CTX_set_tmp_dh(s->ssl_ctx,dh);
837: SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_DH_USE);
838: DH_free(dh);
839: #else
840: if (!buffer_is_empty(s->ssl_dh_file)) {
841: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: openssl compiled without DH support, can't load parameters from", s->ssl_dh_file->ptr);
842: }
843: #endif
844:
845: #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
846: #ifndef OPENSSL_NO_ECDH
847: /* Support for Elliptic-Curve Diffie-Hellman key exchange */
848: if (!buffer_is_empty(s->ssl_ec_curve)) {
849: /* OpenSSL only supports the "named curves" from RFC 4492, section 5.1.1. */
850: nid = OBJ_sn2nid((char *) s->ssl_ec_curve->ptr);
851: if (nid == 0) {
852: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: Unknown curve name", s->ssl_ec_curve->ptr);
853: return -1;
854: }
855: } else {
856: /* Default curve */
857: nid = OBJ_sn2nid("prime256v1");
858: }
859: ecdh = EC_KEY_new_by_curve_name(nid);
860: if (ecdh == NULL) {
861: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: Unable to create curve", s->ssl_ec_curve->ptr);
862: return -1;
863: }
864: SSL_CTX_set_tmp_ecdh(s->ssl_ctx,ecdh);
865: SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_ECDH_USE);
866: EC_KEY_free(ecdh);
867: #endif
868: #endif
869:
1.1.1.2 misho 870: /* load all ssl.ca-files specified in the config into each SSL_CTX to be prepared for SNI */
871: for (j = 0; j < srv->config_context->used; j++) {
872: specific_config *s1 = srv->config_storage[j];
873:
874: if (!buffer_is_empty(s1->ssl_ca_file)) {
875: if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s1->ssl_ca_file->ptr, NULL)) {
1.1 misho 876: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
1.1.1.2 misho 877: ERR_error_string(ERR_get_error(), NULL), s1->ssl_ca_file);
1.1 misho 878: return -1;
879: }
1.1.1.2 misho 880: }
881: }
882:
883: if (s->ssl_verifyclient) {
884: if (NULL == s->ssl_ca_file_cert_names) {
885: log_error_write(srv, __FILE__, __LINE__, "s",
886: "SSL: You specified ssl.verifyclient.activate but no ca_file"
1.1 misho 887: );
1.1.1.2 misho 888: return -1;
1.1 misho 889: }
1.1.1.2 misho 890: SSL_CTX_set_client_CA_list(s->ssl_ctx, SSL_dup_CA_list(s->ssl_ca_file_cert_names));
891: SSL_CTX_set_verify(
892: s->ssl_ctx,
893: SSL_VERIFY_PEER | (s->ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
894: NULL
1.1 misho 895: );
1.1.1.2 misho 896: SSL_CTX_set_verify_depth(s->ssl_ctx, s->ssl_verifyclient_depth);
1.1 misho 897: }
898:
1.1.1.2 misho 899: if (SSL_CTX_use_certificate(s->ssl_ctx, s->ssl_pemfile_x509) < 0) {
1.1 misho 900: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
901: ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
902: return -1;
903: }
904:
1.1.1.2 misho 905: if (SSL_CTX_use_PrivateKey(s->ssl_ctx, s->ssl_pemfile_pkey) < 0) {
1.1 misho 906: log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
907: ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
908: return -1;
909: }
910:
911: if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
912: log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
913: "Private key does not match the certificate public key, reason:",
914: ERR_error_string(ERR_get_error(), NULL),
915: s->ssl_pemfile);
916: return -1;
917: }
918: SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1);
919: SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
920:
921: # ifndef OPENSSL_NO_TLSEXT
922: if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) ||
923: !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) {
924: log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
925: "failed to initialize TLS servername callback, openssl library does not support TLS servername extension");
926: return -1;
927: }
928: # endif
929: }
930: #endif
931:
932: b = buffer_init();
933:
934: buffer_copy_string_buffer(b, srv->srvconf.bindhost);
935: buffer_append_string_len(b, CONST_STR_LEN(":"));
936: buffer_append_long(b, srv->srvconf.port);
937:
938: if (0 != network_server_init(srv, b, srv->config_storage[0])) {
1.1.1.2 misho 939: buffer_free(b);
1.1 misho 940: return -1;
941: }
942: buffer_free(b);
943:
944: #ifdef USE_OPENSSL
945: srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
946: #endif
947:
948: /* get a usefull default */
949: backend = network_backends[0].nb;
950:
951: /* match name against known types */
952: if (!buffer_is_empty(srv->srvconf.network_backend)) {
953: for (i = 0; network_backends[i].name; i++) {
954: /**/
955: if (buffer_is_equal_string(srv->srvconf.network_backend, network_backends[i].name, strlen(network_backends[i].name))) {
956: backend = network_backends[i].nb;
957: break;
958: }
959: }
960: if (NULL == network_backends[i].name) {
961: /* we don't know it */
962:
963: log_error_write(srv, __FILE__, __LINE__, "sb",
964: "server.network-backend has a unknown value:",
965: srv->srvconf.network_backend);
966:
967: return -1;
968: }
969: }
970:
971: switch(backend) {
972: case NETWORK_BACKEND_WRITE:
973: srv->network_backend_write = network_write_chunkqueue_write;
974: break;
975: #ifdef USE_WRITEV
976: case NETWORK_BACKEND_WRITEV:
977: srv->network_backend_write = network_write_chunkqueue_writev;
978: break;
979: #endif
980: #ifdef USE_LINUX_SENDFILE
981: case NETWORK_BACKEND_LINUX_SENDFILE:
982: srv->network_backend_write = network_write_chunkqueue_linuxsendfile;
983: break;
984: #endif
985: #ifdef USE_FREEBSD_SENDFILE
986: case NETWORK_BACKEND_FREEBSD_SENDFILE:
987: srv->network_backend_write = network_write_chunkqueue_freebsdsendfile;
988: break;
989: #endif
990: #ifdef USE_SOLARIS_SENDFILEV
991: case NETWORK_BACKEND_SOLARIS_SENDFILEV:
992: srv->network_backend_write = network_write_chunkqueue_solarissendfilev;
993: break;
994: #endif
995: default:
996: return -1;
997: }
998:
999: /* check for $SERVER["socket"] */
1000: for (i = 1; i < srv->config_context->used; i++) {
1001: data_config *dc = (data_config *)srv->config_context->data[i];
1002: specific_config *s = srv->config_storage[i];
1003:
1004: /* not our stage */
1005: if (COMP_SERVER_SOCKET != dc->comp) continue;
1006:
1007: if (dc->cond != CONFIG_COND_EQ) continue;
1008:
1009: /* check if we already know this socket,
1010: * if yes, don't init it */
1011: for (j = 0; j < srv->srv_sockets.used; j++) {
1012: if (buffer_is_equal(srv->srv_sockets.ptr[j]->srv_token, dc->string)) {
1013: break;
1014: }
1015: }
1016:
1017: if (j == srv->srv_sockets.used) {
1018: if (0 != network_server_init(srv, dc->string, s)) return -1;
1019: }
1020: }
1021:
1022: return 0;
1023: }
1024:
1025: int network_register_fdevents(server *srv) {
1026: size_t i;
1027:
1028: if (-1 == fdevent_reset(srv->ev)) {
1029: return -1;
1030: }
1031:
1032: /* register fdevents after reset */
1033: for (i = 0; i < srv->srv_sockets.used; i++) {
1034: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1035:
1036: fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
1037: fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
1038: }
1039: return 0;
1040: }
1041:
1042: int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
1043: int ret = -1;
1044: off_t written = 0;
1045: #ifdef TCP_CORK
1046: int corked = 0;
1047: #endif
1048: server_socket *srv_socket = con->srv_socket;
1049:
1050: if (con->conf.global_kbytes_per_second) {
1051: off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr);
1052: if (limit <= 0) {
1053: /* we reached the global traffic limit */
1054:
1055: con->traffic_limit_reached = 1;
1056: joblist_append(srv, con);
1057:
1058: return 1;
1059: } else {
1060: if (max_bytes > limit) max_bytes = limit;
1061: }
1062: }
1063:
1064: if (con->conf.kbytes_per_second) {
1065: off_t limit = con->conf.kbytes_per_second * 1024 - con->bytes_written_cur_second;
1066: if (limit <= 0) {
1067: /* we reached the traffic limit */
1068:
1069: con->traffic_limit_reached = 1;
1070: joblist_append(srv, con);
1071:
1072: return 1;
1073: } else {
1074: if (max_bytes > limit) max_bytes = limit;
1075: }
1076: }
1077:
1078: written = cq->bytes_out;
1079:
1080: #ifdef TCP_CORK
1081: /* Linux: put a cork into the socket as we want to combine the write() calls
1082: * but only if we really have multiple chunks
1083: */
1084: if (cq->first && cq->first->next) {
1085: corked = 1;
1086: setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
1087: }
1088: #endif
1089:
1090: if (srv_socket->is_ssl) {
1091: #ifdef USE_OPENSSL
1092: ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq, max_bytes);
1093: #endif
1094: } else {
1095: ret = srv->network_backend_write(srv, con, con->fd, cq, max_bytes);
1096: }
1097:
1098: if (ret >= 0) {
1099: chunkqueue_remove_finished_chunks(cq);
1100: ret = chunkqueue_is_empty(cq) ? 0 : 1;
1101: }
1102:
1103: #ifdef TCP_CORK
1104: if (corked) {
1105: corked = 0;
1106: setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
1107: }
1108: #endif
1109:
1110: written = cq->bytes_out - written;
1111: con->bytes_written += written;
1112: con->bytes_written_cur_second += written;
1113:
1114: *(con->conf.global_bytes_per_second_cnt_ptr) += written;
1115:
1116: return ret;
1117: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>