[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [PATCH] nbd-server: handle auth for v6-mapped IPv4 addresses



On 08/02/2021 23:42, Graham R. Cobb wrote:
> This patch adds support for using IPv4 addresses in the nbd-server auth file
> even if the socket provides v6-mapped addresses. It extends the comparison
> code in address_matches to handle the two cases where the auth file and the
> socket use different address families.
> 
> This fixes issue #35 in the github repository.
> 
> Signed-off-by: Graham R. Cobb <g.nbd@cobb.uk.net>

No comments or reviewed-by so far. I am not sure of the protocol for
this mailing list, but this is a gentle ping :-)

> ---
>  nbdsrv.c | 30 ++++++++++++++++++++++++------
>  1 file changed, 24 insertions(+), 6 deletions(-)
> 
> diff --git a/nbdsrv.c b/nbdsrv.c
> index 168d425..01ba1b2 100644
> --- a/nbdsrv.c
> +++ b/nbdsrv.c
> @@ -35,6 +35,9 @@ bool address_matches(const char* mask, const struct sockaddr* addr, GError** err
>  	char privmask[strlen(mask)+1];
>  	int masklen;
>  	int addrlen = addr->sa_family == AF_INET ? 4 : 16;
> +#define IPV4_MAP_PREFIX 12
> +	uint8_t ipv4_mapped[IPV4_MAP_PREFIX+4] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> +		255, 255, 0, 0, 0, 0};
>  
>  	strcpy(privmask, mask);
>  
> @@ -61,12 +64,9 @@ bool address_matches(const char* mask, const struct sockaddr* addr, GError** err
>  		uint8_t* byte_t;
>  		uint8_t mask = 0;
>  		int len_left = masklen;
> -		if(res->ai_family != addr->sa_family) {
> -			msg(LOG_DEBUG, "client address does not match %d/%d: address family mismatch (IPv4 vs IPv6?)",
> -			    (int)res->ai_family, (int)addr->sa_family);
> -			goto next;
> -		}
> -		switch(addr->sa_family) {
> +		if(res->ai_family == addr->sa_family) {
> +			/* Both addresses are the same address family so do a simple comparison */
> +			switch(addr->sa_family) {
>  			case AF_INET:
>  				byte_s = (const uint8_t*)(&(((struct sockaddr_in*)addr)->sin_addr));
>  				byte_t = (uint8_t*)(&(((struct sockaddr_in*)(res->ai_addr))->sin_addr));
> @@ -75,6 +75,24 @@ bool address_matches(const char* mask, const struct sockaddr* addr, GError** err
>  				byte_s = (const uint8_t*)(&(((struct sockaddr_in6*)addr)->sin6_addr));
>  				byte_t = (uint8_t*)(&(((struct sockaddr_in6*)(res->ai_addr))->sin6_addr));
>  				break;
> +			}
> +		} else {
> +			/* Addresses are different families, compare IPv4-mapped IPv6 address */
> +			switch(addr->sa_family) {
> +			case AF_INET:
> +				/* Map client address to IPv6 for comparison */
> +				memcpy(&ipv4_mapped[IPV4_MAP_PREFIX], &(((struct sockaddr_in*)addr)->sin_addr), 4);
> +				byte_s = (const uint8_t*)&ipv4_mapped;
> +				byte_t = (uint8_t*)(&(((struct sockaddr_in6*)(res->ai_addr))->sin6_addr));
> +				len_left += IPV4_MAP_PREFIX * 8;
> +				break;
> +			case AF_INET6:
> +				byte_s = (const uint8_t*)(&(((struct sockaddr_in6*)addr)->sin6_addr));
> +				/* Map res to IPv6 for comparison */
> +				memcpy(&ipv4_mapped[IPV4_MAP_PREFIX], &(((struct sockaddr_in*)(res->ai_addr))->sin_addr), 4);
> +				byte_t = &ipv4_mapped[0];
> +				break;
> +			}
>  		}
>  		while(len_left >= 8) {
>  			if(*byte_s != *byte_t) {
> 


Reply to: