diff --git a/ChangeLog b/ChangeLog index e28d166b9..64d132c0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -45,6 +45,7 @@ API Changes mbedtls_x509_ctr_verify_info() mbedtls_x509_crt_verify() (flags, f_vrfy -> needs to be update) mbedtls_ssl_conf_verify() (f_vrfy -> needs to be updated) + * net_accept() gained new arguments for the size of the client_ip buffer. * In the threading layer, mbedtls_mutex_init() and mbedtls_mutex_free() now return void. * ecdsa_write_signature() gained an addtional md_alg argument and diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index c3b0b1573..3dd90a9b8 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -62,7 +62,7 @@ * DES 1 0x0032-0x0032 * CTR_DBRG 4 0x0034-0x003A * ENTROPY 3 0x003C-0x0040 - * NET 9 0x0042-0x0052 + * NET 9 0x0042-0x0052 0x0043-0x0043 * ENTROPY 1 0x0058-0x0058 * ASN1 7 0x0060-0x006C * MD2 1 0x0070-0x0070 diff --git a/include/mbedtls/net.h b/include/mbedtls/net.h index 586ee0b36..55db27d89 100644 --- a/include/mbedtls/net.h +++ b/include/mbedtls/net.h @@ -44,6 +44,7 @@ #define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ #define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ #define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ +#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ #define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ @@ -96,17 +97,21 @@ int mbedtls_net_bind( int *fd, const char *bind_ip, int port, int proto ); * \param bind_fd Relevant socket * \param client_fd Will contain the connected client socket * \param client_ip Will contain the client IP address - * Must be at least 4 bytes, or 16 if IPv6 is supported + * \param buf_size Size of the client_ip buffer + * \param ip_len Will receive the size of the client IP written * - * \return 0 if successful, MBEDTLS_ERR_NET_ACCEPT_FAILED, or - * MBEDTLS_ERR_SSL_WANT_READ is bind_fd was set to + * \return 0 if successful, or + * MBEDTLS_ERR_NET_ACCEPT_FAILED, or + * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, + * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to * non-blocking and accept() is blocking. * * \note With UDP, connects the bind_fd to the client and just copy * its descriptor to client_fd. New clients will not be able * to connect until you close the socket and bind a new one. */ -int mbedtls_net_accept( int bind_fd, int *client_fd, void *client_ip ); +int mbedtls_net_accept( int bind_fd, int *client_fd, + void *client_ip, size_t buf_size, size_t *ip_len ); /** * \brief Set the socket blocking diff --git a/library/error.c b/library/error.c index 36b9032a1..2775a4091 100644 --- a/library/error.c +++ b/library/error.c @@ -683,6 +683,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" ); if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) ) mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); + if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" ); #endif /* MBEDTLS_NET_C */ #if defined(MBEDTLS_OID_C) diff --git a/library/net.c b/library/net.c index 568a244e9..8eb51727e 100644 --- a/library/net.c +++ b/library/net.c @@ -293,7 +293,8 @@ static int net_would_block( int fd ) /* * Accept a connection from a remote client */ -int mbedtls_net_accept( int bind_fd, int *client_fd, void *client_ip ) +int mbedtls_net_accept( int bind_fd, int *client_fd, + void *client_ip, size_t buf_size, size_t *ip_len ) { int ret; int type; @@ -353,14 +354,22 @@ int mbedtls_net_accept( int bind_fd, int *client_fd, void *client_ip ) if( client_addr.ss_family == AF_INET ) { struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; - memcpy( client_ip, &addr4->sin_addr.s_addr, - sizeof( addr4->sin_addr.s_addr ) ); + *ip_len = sizeof( addr4->sin_addr.s_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); } else { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; - memcpy( client_ip, &addr6->sin6_addr.s6_addr, - sizeof( addr6->sin6_addr.s6_addr ) ); + *ip_len = sizeof( addr6->sin6_addr.s6_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); } } diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 68a82e33f..9ed6e36a4 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -173,7 +173,8 @@ int main( void ) goto exit; } - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + NULL, 0, NULL ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c index ba74ebd6c..000ad0320 100644 --- a/programs/ssl/dtls_server.c +++ b/programs/ssl/dtls_server.c @@ -94,6 +94,7 @@ int main( void ) unsigned char buf[1024]; const char *pers = "dtls_server"; unsigned char client_ip[16] = { 0 }; + size_t cliip_len; mbedtls_ssl_cookie_ctx cookie_ctx; mbedtls_entropy_context entropy; @@ -263,7 +264,8 @@ reset: printf( " . Waiting for a remote connection ..." ); fflush( stdout ); - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, client_ip ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + client_ip, sizeof( client_ip ), &cliip_len ) ) != 0 ) { printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); goto exit; @@ -277,8 +279,8 @@ reset: } /* For HelloVerifyRequest cookies */ - if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl, client_ip, - sizeof( client_ip ) ) ) != 0 ) + if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl, + client_ip, cliip_len ) ) != 0 ) { printf( " failed\n ! " "mbedtls_ssl_set_client_transport_id() returned -0x%x\n\n", -ret ); diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c index 06c479e7b..1f50c258d 100644 --- a/programs/ssl/ssl_fork_server.c +++ b/programs/ssl/ssl_fork_server.c @@ -220,7 +220,8 @@ int main( void ) mbedtls_printf( " . Waiting for a remote connection ..." ); fflush( stdout ); - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + NULL, 0, NULL ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c index 7d710bed9..2f414bf52 100644 --- a/programs/ssl/ssl_pthread_server.c +++ b/programs/ssl/ssl_pthread_server.c @@ -472,7 +472,8 @@ reset: mbedtls_printf( " [ main ] Waiting for a remote connection\n" ); - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + NULL, 0, NULL ) ) != 0 ) { mbedtls_printf( " [ main ] failed: mbedtls_net_accept returned -0x%04x\n", ret ); goto exit; diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c index a919ad9d8..6c837e9a3 100644 --- a/programs/ssl/ssl_server.c +++ b/programs/ssl/ssl_server.c @@ -246,7 +246,8 @@ reset: mbedtls_printf( " . Waiting for a remote connection ..." ); fflush( stdout ); - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + NULL, 0, NULL ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); goto exit; diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 7dbf414b8..f0ef8511f 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -710,6 +710,7 @@ int main( int argc, char *argv[] ) #endif const char *pers = "ssl_server2"; unsigned char client_ip[16] = { 0 }; + size_t cliip_len; #if defined(MBEDTLS_SSL_COOKIE_C) mbedtls_ssl_cookie_ctx cookie_ctx; #endif @@ -1787,7 +1788,8 @@ reset: mbedtls_printf( " . Waiting for a remote connection ..." ); fflush( stdout ); - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, client_ip ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + client_ip, sizeof( client_ip ), &cliip_len ) ) != 0 ) { #if !defined(_WIN32) if( received_sigterm ) @@ -1817,8 +1819,8 @@ reset: #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { - if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl, client_ip, - sizeof( client_ip ) ) ) != 0 ) + if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl, + client_ip, cliip_len ) ) != 0 ) { mbedtls_printf( " failed\n ! " "mbedtls_ssl_set_client_transport_id() returned -0x%x\n\n", -ret ); diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c index 28b5eaab9..40526688f 100644 --- a/programs/test/udp_proxy.c +++ b/programs/test/udp_proxy.c @@ -534,7 +534,8 @@ accept: mbedtls_printf( " . Waiting for a remote connection ..." ); fflush( stdout ); - if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) + if( ( ret = mbedtls_net_accept( listen_fd, &client_fd, + NULL, 0, NULL ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); goto exit;