2016-03-19 15:14:35 +00:00
# include "first.h"
2005-02-20 14:27:00 +00:00
# include "network.h"
# include "fdevent.h"
# include "log.h"
# include "connections.h"
# include "plugin.h"
# include "joblist.h"
2009-10-14 14:32:24 +00:00
# include "configfile.h"
2005-02-20 14:27:00 +00:00
# include "network_backends.h"
# include "sys-mmap.h"
# include "sys-socket.h"
2009-10-11 14:31:42 +00:00
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <errno.h>
# include <fcntl.h>
# include <unistd.h>
# include <string.h>
# include <stdlib.h>
# include <assert.h>
2005-02-20 14:27:00 +00:00
# ifdef USE_OPENSSL
2006-10-04 13:26:23 +00:00
# include <openssl / ssl.h>
# include <openssl / err.h>
# include <openssl / rand.h>
2013-06-29 12:46:00 +00:00
# ifndef OPENSSL_NO_DH
# include <openssl / dh.h>
# endif
2011-12-27 13:45:36 +00:00
# include <openssl / bn.h>
# if OPENSSL_VERSION_NUMBER >= 0x0090800fL
# ifndef OPENSSL_NO_ECDH
# include <openssl / ecdh.h>
# endif
# endif
2005-02-20 14:27:00 +00:00
# endif
2011-11-30 20:57:54 +00:00
# ifdef USE_OPENSSL
2011-11-30 18:40:08 +00:00
static void ssl_info_callback ( const SSL * ssl , int where , int ret ) {
UNUSED ( ret ) ;
if ( 0 ! = ( where & SSL_CB_HANDSHAKE_START ) ) {
connection * con = SSL_get_app_data ( ssl ) ;
+ + con - > renegotiations ;
}
}
2011-11-30 20:57:54 +00:00
# endif
2011-11-30 18:40:08 +00:00
2010-08-06 21:57:15 +00:00
static handler_t network_server_handle_fdevent ( server * srv , void * context , int revents ) {
2005-02-20 14:27:00 +00:00
server_socket * srv_socket = ( server_socket * ) context ;
connection * con ;
2005-09-23 16:31:49 +00:00
int loops = 0 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
UNUSED ( context ) ;
2006-10-04 13:26:23 +00:00
2010-08-06 21:57:19 +00:00
if ( 0 = = ( revents & FDEVENT_IN ) ) {
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sdd " ,
2005-02-20 14:27:00 +00:00
" strange event for server socket " ,
srv_socket - > fd ,
revents ) ;
2005-03-01 23:01:12 +00:00
return HANDLER_ERROR ;
2005-02-20 14:27:00 +00:00
}
2005-09-23 16:31:49 +00:00
/* accept()s at most 100 connections directly
*
2006-10-04 13:26:23 +00:00
* we jump out after 100 to give the waiting connections a chance */
2005-09-23 16:31:49 +00:00
for ( loops = 0 ; loops < 100 & & NULL ! = ( con = connection_accept ( srv , srv_socket ) ) ; loops + + ) {
2005-02-20 14:27:00 +00:00
connection_state_machine ( srv , con ) ;
}
return HANDLER_GO_ON ;
}
2009-10-14 13:39:59 +00:00
# if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
2009-10-14 14:32:24 +00:00
static int network_ssl_servername_callback ( SSL * ssl , int * al , server * srv ) {
2009-10-14 13:39:59 +00:00
const char * servername ;
connection * con = ( connection * ) SSL_get_app_data ( ssl ) ;
2009-10-14 14:32:24 +00:00
UNUSED ( al ) ;
2009-10-14 13:39:59 +00:00
buffer_copy_string ( con - > uri . scheme , " https " ) ;
if ( NULL = = ( servername = SSL_get_servername ( ssl , TLSEXT_NAMETYPE_host_name ) ) ) {
2009-10-16 22:06:22 +00:00
#if 0
/* this "error" just means the client didn't support it */
2009-10-14 13:39:59 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " SSL: " ,
" failed to get TLS server name " ) ;
2009-10-16 22:06:22 +00:00
# endif
2009-10-14 13:39:59 +00:00
return SSL_TLSEXT_ERR_NOACK ;
}
buffer_copy_string ( con - > tlsext_server_name , servername ) ;
buffer_to_lower ( con - > tlsext_server_name ) ;
2010-04-28 19:08:11 +00:00
/* Sometimes this is still set, confusing COMP_HTTP_HOST */
buffer_reset ( con - > uri . authority ) ;
2009-10-14 13:39:59 +00:00
config_cond_cache_reset ( srv , con ) ;
config_setup_connection ( srv , con ) ;
2016-02-21 18:32:17 +00:00
con - > conditional_is_valid [ COMP_SERVER_SOCKET ] = 1 ;
con - > conditional_is_valid [ COMP_HTTP_SCHEME ] = 1 ;
con - > conditional_is_valid [ COMP_HTTP_HOST ] = 1 ;
config_patch_connection ( srv , con ) ;
2009-10-14 13:39:59 +00:00
2013-11-05 15:29:07 +00:00
if ( NULL = = con - > conf . ssl_pemfile_x509 | | NULL = = con - > conf . ssl_pemfile_pkey ) {
/* x509/pkey available <=> pemfile was set <=> pemfile got patched: so this should never happen, unless you nest $SERVER["socket"] */
2009-10-14 13:39:59 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ssb " , " SSL: " ,
2013-11-05 15:29:07 +00:00
" no certificate/private key for TLS server name " , con - > tlsext_server_name ) ;
2009-10-14 13:39:59 +00:00
return SSL_TLSEXT_ERR_ALERT_FATAL ;
}
2013-11-05 15:29:07 +00:00
/* first set certificate! setting private key checks whether certificate matches it */
if ( ! SSL_use_certificate ( ssl , con - > conf . ssl_pemfile_x509 ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ssb:s " , " SSL: " ,
" failed to set certificate for TLS server name " , con - > tlsext_server_name ,
ERR_error_string ( ERR_get_error ( ) , NULL ) ) ;
2009-10-14 13:39:59 +00:00
return SSL_TLSEXT_ERR_ALERT_FATAL ;
}
2013-11-05 15:29:07 +00:00
if ( ! SSL_use_PrivateKey ( ssl , con - > conf . ssl_pemfile_pkey ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ssb:s " , " SSL: " ,
" failed to set private key for TLS server name " , con - > tlsext_server_name ,
ERR_error_string ( ERR_get_error ( ) , NULL ) ) ;
return SSL_TLSEXT_ERR_ALERT_FATAL ;
}
if ( con - > conf . ssl_verifyclient ) {
if ( NULL = = con - > conf . ssl_ca_file_cert_names ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ssb:s " , " SSL: " ,
" can't verify client without ssl.ca-file for TLS server name " , con - > tlsext_server_name ,
ERR_error_string ( ERR_get_error ( ) , NULL ) ) ;
return SSL_TLSEXT_ERR_ALERT_FATAL ;
}
SSL_set_client_CA_list ( ssl , SSL_dup_CA_list ( con - > conf . ssl_ca_file_cert_names ) ) ;
/* forcing verification here is really not that useful - a client could just connect without SNI */
SSL_set_verify (
ssl ,
SSL_VERIFY_PEER | ( con - > conf . ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0 ) ,
NULL
) ;
SSL_set_verify_depth ( ssl , con - > conf . ssl_verifyclient_depth ) ;
2016-03-19 13:27:13 +00:00
} else {
SSL_set_verify ( ssl , SSL_VERIFY_NONE , NULL ) ;
2013-11-05 15:29:07 +00:00
}
2009-10-14 13:39:59 +00:00
return SSL_TLSEXT_ERR_OK ;
}
# endif
2009-03-07 21:05:37 +00:00
static int network_server_init ( server * srv , buffer * host_token , specific_config * s ) {
2005-02-20 14:27:00 +00:00
int val ;
socklen_t addr_len ;
server_socket * srv_socket ;
unsigned int port = 0 ;
const char * host ;
buffer * b ;
2005-11-23 10:46:21 +00:00
int is_unix_domain_socket = 0 ;
2006-01-14 17:02:44 +00:00
int fd ;
2016-03-26 13:39:54 +00:00
int err ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
# ifdef __WIN32
WORD wVersionRequested ;
WSADATA wsaData ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
wVersionRequested = MAKEWORD ( 2 , 2 ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
err = WSAStartup ( wVersionRequested , & wsaData ) ;
if ( err ! = 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return - 1 ;
}
# endif
2016-03-26 13:39:54 +00:00
err = - 1 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
srv_socket = calloc ( 1 , sizeof ( * srv_socket ) ) ;
2016-01-30 13:59:07 +00:00
force_assert ( NULL ! = srv_socket ) ;
2005-02-20 14:27:00 +00:00
srv_socket - > fd = - 1 ;
2009-09-01 14:03:59 +00:00
srv_socket - > fde_ndx = - 1 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
srv_socket - > srv_token = buffer_init ( ) ;
2015-02-08 12:37:10 +00:00
buffer_copy_buffer ( srv_socket - > srv_token , host_token ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
b = buffer_init ( ) ;
2015-02-08 12:37:10 +00:00
buffer_copy_buffer ( b , host_token ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
host = b - > ptr ;
2006-10-04 13:26:23 +00:00
2005-11-23 10:46:21 +00:00
if ( host [ 0 ] = = ' / ' ) {
/* host is a unix-domain-socket */
is_unix_domain_socket = 1 ;
2016-03-19 13:06:54 +00:00
} else {
/* ipv4:port
* [ ipv6 ] : port
*/
size_t len = buffer_string_length ( b ) ;
char * sp = NULL ;
2016-03-19 13:06:56 +00:00
if ( 0 = = len ) {
log_error_write ( srv , __FILE__ , __LINE__ , " s " , " value of $SERVER[ \" socket \" ] must not be empty " ) ;
2016-03-19 13:06:54 +00:00
goto error_free_socket ;
2016-03-19 13:06:56 +00:00
}
if ( ( b - > ptr [ 0 ] = = ' [ ' & & b - > ptr [ len - 1 ] = = ' ] ' ) | | NULL = = ( sp = strrchr ( b - > ptr , ' : ' ) ) ) {
/* use server.port if set in config, or else default from config_set_defaults() */
port = srv - > srvconf . port ;
sp = b - > ptr + len ; /* point to '\0' at end of string so end of IPv6 address can be found below */
2016-03-19 13:06:54 +00:00
} else {
/* found ip:port separator at *sp; port doesn't end in ']', so *sp hopefully doesn't split an IPv6 address */
* ( sp + + ) = ' \0 ' ;
port = strtol ( sp , NULL , 10 ) ;
}
2006-10-04 13:26:23 +00:00
2016-03-19 13:06:54 +00:00
/* check for [ and ] */
if ( b - > ptr [ 0 ] = = ' [ ' & & * ( sp - 1 ) = = ' ] ' ) {
* ( sp - 1 ) = ' \0 ' ;
host + + ;
s - > use_ipv6 = 1 ;
}
if ( port = = 0 | | port > 65535 ) {
2016-03-19 13:06:56 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sd " , " port not set or out of range: " , port ) ;
2016-03-19 13:06:54 +00:00
goto error_free_socket ;
}
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( * host = = ' \0 ' ) host = NULL ;
2005-11-23 10:46:21 +00:00
if ( is_unix_domain_socket ) {
# ifdef HAVE_SYS_UN_H
srv_socket - > addr . plain . sa_family = AF_UNIX ;
2006-10-04 13:26:23 +00:00
2005-11-23 10:46:21 +00:00
if ( - 1 = = ( srv_socket - > fd = socket ( srv_socket - > addr . plain . sa_family , SOCK_STREAM , 0 ) ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socket failed: " , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-11-23 10:46:21 +00:00
}
# else
log_error_write ( srv , __FILE__ , __LINE__ , " s " ,
" ERROR: Unix Domain sockets are not supported. " ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-11-23 10:46:21 +00:00
# endif
}
2005-02-20 14:27:00 +00:00
# ifdef HAVE_IPV6
if ( s - > use_ipv6 ) {
srv_socket - > addr . plain . sa_family = AF_INET6 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( - 1 = = ( srv_socket - > fd = socket ( srv_socket - > addr . plain . sa_family , SOCK_STREAM , IPPROTO_TCP ) ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socket failed: " , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
}
# endif
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( srv_socket - > fd = = - 1 ) {
srv_socket - > addr . plain . sa_family = AF_INET ;
if ( - 1 = = ( srv_socket - > fd = socket ( srv_socket - > addr . plain . sa_family , SOCK_STREAM , IPPROTO_TCP ) ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socket failed: " , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
}
2006-10-04 13:26:23 +00:00
2009-07-11 09:01:18 +00:00
/* set FD_CLOEXEC now, fdevent_fcntl_set is called later; needed for pipe-logger forks */
2014-02-16 13:08:29 +00:00
fd_close_on_exec ( srv_socket - > fd ) ;
2009-07-11 09:01:18 +00:00
2005-02-20 14:27:00 +00:00
/* */
srv - > cur_fds = srv_socket - > fd ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
val = 1 ;
if ( setsockopt ( srv_socket - > fd , SOL_SOCKET , SO_REUSEADDR , & val , sizeof ( val ) ) < 0 ) {
2010-08-07 13:16:16 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socketsockopt(SO_REUSEADDR) failed: " , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
switch ( srv_socket - > addr . plain . sa_family ) {
# ifdef HAVE_IPV6
case AF_INET6 :
memset ( & srv_socket - > addr , 0 , sizeof ( struct sockaddr_in6 ) ) ;
srv_socket - > addr . ipv6 . sin6_family = AF_INET6 ;
if ( host = = NULL ) {
srv_socket - > addr . ipv6 . sin6_addr = in6addr_any ;
2010-08-07 13:16:16 +00:00
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 " ) ;
2005-02-20 14:27:00 +00:00
} else {
struct addrinfo hints , * res ;
int r ;
2006-10-04 13:26:23 +00:00
2010-08-07 13:16:16 +00:00
if ( s - > set_v6only ) {
val = 1 ;
if ( - 1 = = setsockopt ( srv_socket - > fd , IPPROTO_IPV6 , IPV6_V6ONLY , & val , sizeof ( val ) ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socketsockopt(IPV6_V6ONLY) failed: " , strerror ( errno ) ) ;
goto error_free_socket ;
}
} else {
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 " ) ;
}
2005-02-20 14:27:00 +00:00
memset ( & hints , 0 , sizeof ( hints ) ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
hints . ai_family = AF_INET6 ;
hints . ai_socktype = SOCK_STREAM ;
hints . ai_protocol = IPPROTO_TCP ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( 0 ! = ( r = getaddrinfo ( host , NULL , & hints , & res ) ) ) {
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ ,
" sssss " , " getaddrinfo failed: " ,
2005-02-20 14:27:00 +00:00
gai_strerror ( r ) , " ' " , host , " ' " ) ;
2006-10-04 13:26:23 +00:00
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
memcpy ( & ( srv_socket - > addr ) , res - > ai_addr , res - > ai_addrlen ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
freeaddrinfo ( res ) ;
}
srv_socket - > addr . ipv6 . sin6_port = htons ( port ) ;
addr_len = sizeof ( struct sockaddr_in6 ) ;
break ;
# endif
case AF_INET :
memset ( & srv_socket - > addr , 0 , sizeof ( struct sockaddr_in ) ) ;
srv_socket - > addr . ipv4 . sin_family = AF_INET ;
if ( host = = NULL ) {
srv_socket - > addr . ipv4 . sin_addr . s_addr = htonl ( INADDR_ANY ) ;
} else {
struct hostent * he ;
if ( NULL = = ( he = gethostbyname ( host ) ) ) {
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ ,
" sds " , " gethostbyname failed: " ,
2005-08-08 16:32:17 +00:00
h_errno , host ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( he - > h_addrtype ! = AF_INET ) {
log_error_write ( srv , __FILE__ , __LINE__ , " sd " , " addr-type != AF_INET: " , he - > h_addrtype ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( he - > h_length ! = sizeof ( struct in_addr ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " sd " , " addr-length != sizeof(in_addr): " , he - > h_length ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
memcpy ( & ( srv_socket - > addr . ipv4 . sin_addr . s_addr ) , he - > h_addr_list [ 0 ] , he - > h_length ) ;
}
srv_socket - > addr . ipv4 . sin_port = htons ( port ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
addr_len = sizeof ( struct sockaddr_in ) ;
2006-10-04 13:26:23 +00:00
2005-11-23 10:46:21 +00:00
break ;
case AF_UNIX :
2015-02-07 11:33:30 +00:00
memset ( & srv_socket - > addr , 0 , sizeof ( struct sockaddr_un ) ) ;
srv_socket - > addr . un . sun_family = AF_UNIX ;
2014-02-16 13:08:43 +00:00
{
size_t hostlen = strlen ( host ) + 1 ;
if ( hostlen > sizeof ( srv_socket - > addr . un . sun_path ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " sS " , " unix socket filename too long: " , host ) ;
goto error_free_socket ;
}
memcpy ( srv_socket - > addr . un . sun_path , host , hostlen ) ;
2006-10-04 13:26:23 +00:00
2015-02-07 11:33:30 +00:00
# if defined(SUN_LEN)
addr_len = SUN_LEN ( & srv_socket - > addr . un ) ;
2005-11-23 10:46:21 +00:00
# else
2015-02-07 11:33:30 +00:00
/* stevens says: */
addr_len = hostlen + sizeof ( srv_socket - > addr . un . sun_family ) ;
2005-11-23 10:46:21 +00:00
# endif
2015-02-07 11:33:30 +00:00
}
2005-11-23 10:46:21 +00:00
2016-03-26 13:39:54 +00:00
if ( srv - > srvconf . preflight_check ) break ;
2006-01-14 17:02:44 +00:00
/* check if the socket exists and try to connect to it. */
if ( - 1 ! = ( fd = connect ( srv_socket - > fd , ( struct sockaddr * ) & ( srv_socket - > addr ) , addr_len ) ) ) {
close ( fd ) ;
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " ,
" server socket is still in use: " ,
2006-01-14 17:02:44 +00:00
host ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2006-01-14 17:02:44 +00:00
}
/* connect failed */
switch ( errno ) {
case ECONNREFUSED :
unlink ( host ) ;
break ;
case ENOENT :
break ;
default :
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sds " ,
" testing socket failed: " ,
2006-01-14 17:02:44 +00:00
host , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2006-01-14 17:02:44 +00:00
}
2005-02-20 14:27:00 +00:00
break ;
default :
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2016-03-26 13:39:54 +00:00
if ( srv - > srvconf . preflight_check ) {
err = 0 ;
goto error_free_socket ;
}
2005-02-20 14:27:00 +00:00
if ( 0 ! = bind ( srv_socket - > fd , ( struct sockaddr * ) & ( srv_socket - > addr ) , addr_len ) ) {
2006-01-14 17:02:44 +00:00
switch ( srv_socket - > addr . plain . sa_family ) {
case AF_UNIX :
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sds " ,
" can't bind to socket: " ,
2006-01-14 17:02:44 +00:00
host , strerror ( errno ) ) ;
break ;
default :
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ssds " ,
" can't bind to port: " ,
2006-01-14 17:02:44 +00:00
host , port , strerror ( errno ) ) ;
break ;
}
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2016-03-30 20:17:17 +00:00
if ( - 1 = = listen ( srv_socket - > fd , s - > listen_backlog ) ) {
2005-02-20 14:27:00 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " listen failed: " , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2013-07-31 20:23:21 +00:00
if ( s - > ssl_enabled ) {
2005-02-20 14:27:00 +00:00
# ifdef USE_OPENSSL
2009-10-14 13:39:59 +00:00
if ( NULL = = ( srv_socket - > ssl_ctx = s - > ssl_ctx ) ) {
2005-02-20 14:27:00 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " s " , " ssl.pemfile has to be set " ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
# else
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " SSL: " ,
2005-02-20 14:27:00 +00:00
" ssl requested but openssl support is not compiled in " ) ;
2006-10-04 13:26:23 +00:00
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2009-04-26 17:59:55 +00:00
# endif
# ifdef TCP_DEFER_ACCEPT
} else if ( s - > defer_accept ) {
int v = s - > defer_accept ;
if ( - 1 = = setsockopt ( srv_socket - > fd , IPPROTO_TCP , TCP_DEFER_ACCEPT , & v , sizeof ( v ) ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " can't set TCP_DEFER_ACCEPT: " , strerror ( errno ) ) ;
}
2005-04-30 10:03:29 +00:00
# endif
} else {
# ifdef SO_ACCEPTFILTER
2009-04-26 17:59:55 +00:00
/* FreeBSD accf_http filter */
struct accept_filter_arg afa ;
2005-04-30 10:03:29 +00:00
memset ( & afa , 0 , sizeof ( afa ) ) ;
strcpy ( afa . af_name , " httpready " ) ;
if ( setsockopt ( srv_socket - > fd , SOL_SOCKET , SO_ACCEPTFILTER , & afa , sizeof ( afa ) ) < 0 ) {
if ( errno ! = ENOENT ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " can't set accept-filter 'httpready': " , strerror ( errno ) ) ;
}
}
2005-02-20 14:27:00 +00:00
# endif
}
2006-10-04 13:26:23 +00:00
2013-07-31 20:23:21 +00:00
srv_socket - > is_ssl = s - > ssl_enabled ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( srv - > srv_sockets . size = = 0 ) {
srv - > srv_sockets . size = 4 ;
srv - > srv_sockets . used = 0 ;
2013-11-13 11:43:26 +00:00
srv - > srv_sockets . ptr = malloc ( srv - > srv_sockets . size * sizeof ( server_socket * ) ) ;
2016-01-30 13:59:07 +00:00
force_assert ( NULL ! = srv - > srv_sockets . ptr ) ;
2005-02-20 14:27:00 +00:00
} else if ( srv - > srv_sockets . used = = srv - > srv_sockets . size ) {
srv - > srv_sockets . size + = 4 ;
2013-11-13 11:43:26 +00:00
srv - > srv_sockets . ptr = realloc ( srv - > srv_sockets . ptr , srv - > srv_sockets . size * sizeof ( server_socket * ) ) ;
2016-01-30 13:59:07 +00:00
force_assert ( NULL ! = srv - > srv_sockets . ptr ) ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
srv - > srv_sockets . ptr [ srv - > srv_sockets . used + + ] = srv_socket ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
buffer_free ( b ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
return 0 ;
2009-09-01 14:03:59 +00:00
error_free_socket :
if ( srv_socket - > fd ! = - 1 ) {
/* check if server fd are already registered */
if ( srv_socket - > fde_ndx ! = - 1 ) {
fdevent_event_del ( srv - > ev , & ( srv_socket - > fde_ndx ) , srv_socket - > fd ) ;
fdevent_unregister ( srv - > ev , srv_socket - > fd ) ;
}
close ( srv_socket - > fd ) ;
}
buffer_free ( srv_socket - > srv_token ) ;
free ( srv_socket ) ;
2012-11-09 14:23:22 +00:00
buffer_free ( b ) ;
2016-03-26 13:39:54 +00:00
return err ; /* -1 if error; 0 if srv->srvconf.preflight_check successful */
2005-02-20 14:27:00 +00:00
}
int network_close ( server * srv ) {
size_t i ;
for ( i = 0 ; i < srv - > srv_sockets . used ; i + + ) {
server_socket * srv_socket = srv - > srv_sockets . ptr [ i ] ;
2006-10-04 13:26:23 +00:00
2005-08-31 09:16:18 +00:00
if ( srv_socket - > fd ! = - 1 ) {
2005-02-20 14:27:00 +00:00
/* check if server fd are already registered */
if ( srv_socket - > fde_ndx ! = - 1 ) {
fdevent_event_del ( srv - > ev , & ( srv_socket - > fde_ndx ) , srv_socket - > fd ) ;
fdevent_unregister ( srv - > ev , srv_socket - > fd ) ;
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
close ( srv_socket - > fd ) ;
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
buffer_free ( srv_socket - > srv_token ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
free ( srv_socket ) ;
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
free ( srv - > srv_sockets . ptr ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
return 0 ;
}
2005-10-31 15:34:00 +00:00
typedef enum {
NETWORK_BACKEND_UNSET ,
NETWORK_BACKEND_WRITE ,
NETWORK_BACKEND_WRITEV ,
2015-08-22 16:00:59 +00:00
NETWORK_BACKEND_SENDFILE ,
2005-10-31 15:34:00 +00:00
} network_backend_t ;
2013-11-05 15:29:07 +00:00
# ifdef USE_OPENSSL
static X509 * x509_load_pem_file ( server * srv , const char * file ) {
BIO * in ;
X509 * x = NULL ;
in = BIO_new ( BIO_s_file ( ) ) ;
if ( NULL = = in ) {
log_error_write ( srv , __FILE__ , __LINE__ , " S " , " SSL: BIO_new(BIO_s_file()) failed " ) ;
goto error ;
}
if ( BIO_read_filename ( in , file ) < = 0 ) {
log_error_write ( srv , __FILE__ , __LINE__ , " SSS " , " SSL: BIO_read_filename(' " , file , " ') failed " ) ;
goto error ;
}
x = PEM_read_bio_X509 ( in , NULL , NULL , NULL ) ;
if ( NULL = = x ) {
log_error_write ( srv , __FILE__ , __LINE__ , " SSS " , " SSL: couldn't read X509 certificate from ' " , file , " ' " ) ;
goto error ;
}
BIO_free ( in ) ;
return x ;
error :
if ( NULL ! = in ) BIO_free ( in ) ;
return NULL ;
}
static EVP_PKEY * evp_pkey_load_pem_file ( server * srv , const char * file ) {
BIO * in ;
EVP_PKEY * x = NULL ;
in = BIO_new ( BIO_s_file ( ) ) ;
if ( NULL = = in ) {
log_error_write ( srv , __FILE__ , __LINE__ , " s " , " SSL: BIO_new(BIO_s_file()) failed " ) ;
goto error ;
}
if ( BIO_read_filename ( in , file ) < = 0 ) {
log_error_write ( srv , __FILE__ , __LINE__ , " SSS " , " SSL: BIO_read_filename(' " , file , " ') failed " ) ;
goto error ;
}
x = PEM_read_bio_PrivateKey ( in , NULL , NULL , NULL ) ;
if ( NULL = = x ) {
log_error_write ( srv , __FILE__ , __LINE__ , " SSS " , " SSL: couldn't read private key from ' " , file , " ' " ) ;
goto error ;
}
BIO_free ( in ) ;
return x ;
error :
if ( NULL ! = in ) BIO_free ( in ) ;
return NULL ;
}
static int network_openssl_load_pemfile ( server * srv , size_t ndx ) {
specific_config * s = srv - > config_storage [ ndx ] ;
# ifdef OPENSSL_NO_TLSEXT
{
2014-01-20 21:31:26 +00:00
data_config * dc = ( data_config * ) srv - > config_context - > data [ ndx ] ;
2013-11-05 15:29:07 +00:00
if ( ( ndx > 0 & & ( COMP_SERVER_SOCKET ! = dc - > comp | | dc - > cond ! = CONFIG_COND_EQ ) )
| | ! s - > ssl_enabled ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " SSL: " ,
" ssl.pemfile only works in SSL socket binding context as openssl version does not support TLS extensions " ) ;
return - 1 ;
}
}
# endif
if ( NULL = = ( s - > ssl_pemfile_x509 = x509_load_pem_file ( srv , s - > ssl_pemfile - > ptr ) ) ) return - 1 ;
if ( NULL = = ( s - > ssl_pemfile_pkey = evp_pkey_load_pem_file ( srv , s - > ssl_pemfile - > ptr ) ) ) return - 1 ;
if ( ! X509_check_private_key ( s - > ssl_pemfile_x509 , s - > ssl_pemfile_pkey ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " sssb " , " SSL: " ,
" Private key does not match the certificate public key, reason: " ,
ERR_error_string ( ERR_get_error ( ) , NULL ) ,
s - > ssl_pemfile ) ;
return - 1 ;
}
return 0 ;
}
# endif
2005-02-20 14:27:00 +00:00
int network_init ( server * srv ) {
buffer * b ;
2013-11-05 15:29:07 +00:00
size_t i , j ;
2005-10-31 15:34:00 +00:00
network_backend_t backend ;
2006-10-04 13:26:23 +00:00
2011-03-13 18:00:09 +00:00
# if OPENSSL_VERSION_NUMBER >= 0x0090800fL
2011-08-22 15:32:55 +00:00
# ifndef OPENSSL_NO_ECDH
2011-03-13 18:00:09 +00:00
EC_KEY * ecdh ;
int nid ;
# endif
2011-08-22 15:32:55 +00:00
# endif
2011-03-13 18:00:09 +00:00
2011-04-24 16:02:55 +00:00
# ifdef USE_OPENSSL
2013-06-29 12:46:00 +00:00
# ifndef OPENSSL_NO_DH
2011-04-24 16:02:55 +00:00
DH * dh ;
2013-06-29 12:46:00 +00:00
# endif
2011-04-24 16:02:55 +00:00
BIO * bio ;
2011-03-13 18:00:09 +00:00
/* 1024-bit MODP Group with 160-bit prime order subgroup (RFC5114)
* - - - - - BEGIN DH PARAMETERS - - - - -
* MIIBDAKBgQCxC4 + WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y
* mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O / rMvdfZDEvXCYSI6cIZpzck7 / 1 vrlZEc4
* + qMaT / VbzMChUa9fDci0vUW / N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV
* w / 00 EmdlpELvuZkF + BBN0lisUH / WQGz / FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0
* sBuIal6RVH + eJ0n01 / vX07mpLuGQnQ0iY / gKdqaiTAh6CR9THb8KAWm2oorWYqTR
* jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5QICAKA =
* - - - - - END DH PARAMETERS - - - - -
*/
2011-04-24 16:02:55 +00:00
static const unsigned char dh1024_p [ ] = {
2011-03-13 18:00:09 +00:00
0xB1 , 0x0B , 0x8F , 0x96 , 0xA0 , 0x80 , 0xE0 , 0x1D , 0xDE , 0x92 , 0xDE , 0x5E ,
0xAE , 0x5D , 0x54 , 0xEC , 0x52 , 0xC9 , 0x9F , 0xBC , 0xFB , 0x06 , 0xA3 , 0xC6 ,
0x9A , 0x6A , 0x9D , 0xCA , 0x52 , 0xD2 , 0x3B , 0x61 , 0x60 , 0x73 , 0xE2 , 0x86 ,
0x75 , 0xA2 , 0x3D , 0x18 , 0x98 , 0x38 , 0xEF , 0x1E , 0x2E , 0xE6 , 0x52 , 0xC0 ,
0x13 , 0xEC , 0xB4 , 0xAE , 0xA9 , 0x06 , 0x11 , 0x23 , 0x24 , 0x97 , 0x5C , 0x3C ,
0xD4 , 0x9B , 0x83 , 0xBF , 0xAC , 0xCB , 0xDD , 0x7D , 0x90 , 0xC4 , 0xBD , 0x70 ,
0x98 , 0x48 , 0x8E , 0x9C , 0x21 , 0x9A , 0x73 , 0x72 , 0x4E , 0xFF , 0xD6 , 0xFA ,
0xE5 , 0x64 , 0x47 , 0x38 , 0xFA , 0xA3 , 0x1A , 0x4F , 0xF5 , 0x5B , 0xCC , 0xC0 ,
0xA1 , 0x51 , 0xAF , 0x5F , 0x0D , 0xC8 , 0xB4 , 0xBD , 0x45 , 0xBF , 0x37 , 0xDF ,
0x36 , 0x5C , 0x1A , 0x65 , 0xE6 , 0x8C , 0xFD , 0xA7 , 0x6D , 0x4D , 0xA7 , 0x08 ,
0xDF , 0x1F , 0xB2 , 0xBC , 0x2E , 0x4A , 0x43 , 0x71 ,
} ;
2011-04-24 16:02:55 +00:00
static const unsigned char dh1024_g [ ] = {
2011-03-13 18:00:09 +00:00
0xA4 , 0xD1 , 0xCB , 0xD5 , 0xC3 , 0xFD , 0x34 , 0x12 , 0x67 , 0x65 , 0xA4 , 0x42 ,
0xEF , 0xB9 , 0x99 , 0x05 , 0xF8 , 0x10 , 0x4D , 0xD2 , 0x58 , 0xAC , 0x50 , 0x7F ,
0xD6 , 0x40 , 0x6C , 0xFF , 0x14 , 0x26 , 0x6D , 0x31 , 0x26 , 0x6F , 0xEA , 0x1E ,
0x5C , 0x41 , 0x56 , 0x4B , 0x77 , 0x7E , 0x69 , 0x0F , 0x55 , 0x04 , 0xF2 , 0x13 ,
0x16 , 0x02 , 0x17 , 0xB4 , 0xB0 , 0x1B , 0x88 , 0x6A , 0x5E , 0x91 , 0x54 , 0x7F ,
0x9E , 0x27 , 0x49 , 0xF4 , 0xD7 , 0xFB , 0xD7 , 0xD3 , 0xB9 , 0xA9 , 0x2E , 0xE1 ,
0x90 , 0x9D , 0x0D , 0x22 , 0x63 , 0xF8 , 0x0A , 0x76 , 0xA6 , 0xA2 , 0x4C , 0x08 ,
0x7A , 0x09 , 0x1F , 0x53 , 0x1D , 0xBF , 0x0A , 0x01 , 0x69 , 0xB6 , 0xA2 , 0x8A ,
0xD6 , 0x62 , 0xA4 , 0xD1 , 0x8E , 0x73 , 0xAF , 0xA3 , 0x2D , 0x77 , 0x9D , 0x59 ,
0x18 , 0xD0 , 0x8B , 0xC8 , 0x85 , 0x8F , 0x4D , 0xCE , 0xF9 , 0x7C , 0x2A , 0x24 ,
0x85 , 0x5E , 0x6E , 0xEB , 0x22 , 0xB3 , 0xB2 , 0xE5 ,
} ;
2011-04-24 16:02:55 +00:00