Blame lib/ext/server_name.c

Packit 549fdc
/*
Packit 549fdc
 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
Packit 549fdc
 * Copyright (C) 2017 Red Hat, Inc.
Packit 549fdc
 *
Packit 549fdc
 * Author: Nikos Mavrogiannopoulos
Packit 549fdc
 *
Packit 549fdc
 * This file is part of GnuTLS.
Packit 549fdc
 *
Packit 549fdc
 * The GnuTLS is free software; you can redistribute it and/or
Packit 549fdc
 * modify it under the terms of the GNU Lesser General Public License
Packit 549fdc
 * as published by the Free Software Foundation; either version 2.1 of
Packit 549fdc
 * the License, or (at your option) any later version.
Packit 549fdc
 *
Packit 549fdc
 * This library is distributed in the hope that it will be useful, but
Packit 549fdc
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 549fdc
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 549fdc
 * Lesser General Public License for more details.
Packit 549fdc
 *
Packit 549fdc
 * You should have received a copy of the GNU Lesser General Public License
Packit 549fdc
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
Packit 549fdc
 *
Packit 549fdc
 */
Packit 549fdc
Packit 549fdc
#include "gnutls_int.h"
Packit 549fdc
#include "auth.h"
Packit 549fdc
#include "errors.h"
Packit 549fdc
#include "num.h"
Packit 549fdc
#include "str.h"
Packit 549fdc
#include <ext/server_name.h>
Packit 549fdc
Packit 549fdc
static int _gnutls_server_name_recv_params(gnutls_session_t session,
Packit 549fdc
					   const uint8_t * data,
Packit 549fdc
					   size_t data_size);
Packit 549fdc
static int _gnutls_server_name_send_params(gnutls_session_t session,
Packit 549fdc
					   gnutls_buffer_st * extdata);
Packit 549fdc
Packit 549fdc
static int _gnutls_server_name_unpack(gnutls_buffer_st * ps,
Packit 549fdc
				      gnutls_ext_priv_data_t * _priv);
Packit 549fdc
static int _gnutls_server_name_pack(gnutls_ext_priv_data_t _priv,
Packit 549fdc
				    gnutls_buffer_st * ps);
Packit 549fdc
static void _gnutls_server_name_deinit_data(gnutls_ext_priv_data_t priv);
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_server_name_set_raw(gnutls_session_t session,
Packit 549fdc
		       gnutls_server_name_type_t type,
Packit 549fdc
		       const void *name, size_t name_length);
Packit 549fdc
Packit 549fdc
const extension_entry_st ext_mod_server_name = {
Packit 549fdc
	.name = "Server Name Indication",
Packit 549fdc
	.type = GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
	.parse_type = GNUTLS_EXT_MANDATORY,
Packit 549fdc
Packit 549fdc
	.recv_func = _gnutls_server_name_recv_params,
Packit 549fdc
	.send_func = _gnutls_server_name_send_params,
Packit 549fdc
	.pack_func = _gnutls_server_name_pack,
Packit 549fdc
	.unpack_func = _gnutls_server_name_unpack,
Packit 549fdc
	.deinit_func = _gnutls_server_name_deinit_data,
Packit 549fdc
	.cannot_be_overriden = 1
Packit 549fdc
};
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * In case of a server: if a NAME_DNS extension type is received then
Packit 549fdc
 * it stores into the session the value of NAME_DNS. The server may
Packit 549fdc
 * use gnutls_ext_get_server_name(), in order to access it.
Packit 549fdc
 *
Packit 549fdc
 * In case of a client: If a proper NAME_DNS extension type is found
Packit 549fdc
 * in the session then it sends the extension to the peer.
Packit 549fdc
 *
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_server_name_recv_params(gnutls_session_t session,
Packit 549fdc
				const uint8_t * data, size_t _data_size)
Packit 549fdc
{
Packit 549fdc
	const unsigned char *p;
Packit 549fdc
	uint16_t len, type;
Packit 549fdc
	ssize_t data_size = _data_size;
Packit 549fdc
	server_name_ext_st *priv = NULL;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	if (session->security_parameters.entity == GNUTLS_SERVER) {
Packit 549fdc
		DECR_LENGTH_RET(data_size, 2, GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
Packit 549fdc
		len = _gnutls_read_uint16(data);
Packit 549fdc
		if (len == 0)
Packit 549fdc
			return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
Packit 549fdc
Packit 549fdc
		if (len != data_size) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		p = data + 2;
Packit 549fdc
Packit 549fdc
		while (data_size > 0) {
Packit 549fdc
			DECR_LEN(data_size, 1);
Packit 549fdc
			type = *p;
Packit 549fdc
			p++;
Packit 549fdc
Packit 549fdc
			DECR_LEN(data_size, 2);
Packit 549fdc
			len = _gnutls_read_uint16(p);
Packit 549fdc
			p += 2;
Packit 549fdc
Packit 549fdc
			if (len == 0) {
Packit 549fdc
				_gnutls_handshake_log
Packit 549fdc
				    ("HSK[%p]: Received server name size of zero\n",
Packit 549fdc
				     session);
Packit 549fdc
				return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
Packit 549fdc
			}
Packit 549fdc
Packit 549fdc
			DECR_LEN(data_size, len);
Packit 549fdc
Packit 549fdc
			if (type == 0) { /* NAME_DNS */
Packit 549fdc
				if (!_gnutls_dnsname_is_valid((char*)p, len))
Packit 549fdc
					return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
Packit 549fdc
Packit 549fdc
				if (len < MAX_SERVER_NAME_SIZE) {
Packit 549fdc
					priv = gnutls_calloc(1, sizeof(*priv));
Packit 549fdc
					if (priv == NULL) {
Packit 549fdc
						gnutls_assert();
Packit 549fdc
						return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
					}
Packit 549fdc
Packit 549fdc
					memcpy(priv->name, p, len);
Packit 549fdc
					priv->name[len] = 0;
Packit 549fdc
Packit 549fdc
					priv->name_length = len;
Packit 549fdc
					priv->type =
Packit 549fdc
					    GNUTLS_NAME_DNS;
Packit 549fdc
Packit 549fdc
					epriv = priv;
Packit 549fdc
					_gnutls_ext_set_session_data(session,
Packit 549fdc
						     GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
						     epriv);
Packit 549fdc
					return 0;
Packit 549fdc
				}
Packit 549fdc
			}
Packit 549fdc
			p += len;
Packit 549fdc
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* returns data_size or a negative number on failure
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_server_name_send_params(gnutls_session_t session,
Packit 549fdc
				gnutls_buffer_st * extdata)
Packit 549fdc
{
Packit 549fdc
	int total_size = 0, ret;
Packit 549fdc
	server_name_ext_st *priv;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_session_data(session,
Packit 549fdc
					 GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
					 &epriv);
Packit 549fdc
	if (ret < 0)
Packit 549fdc
		return 0;
Packit 549fdc
Packit 549fdc
	/* this function sends the client extension data (dnsname)
Packit 549fdc
	 */
Packit 549fdc
	if (session->security_parameters.entity == GNUTLS_CLIENT) {
Packit 549fdc
		priv = epriv;
Packit 549fdc
Packit 549fdc
		if (priv->name_length == 0 || priv->type != GNUTLS_NAME_DNS)
Packit 549fdc
			return 0;
Packit 549fdc
Packit 549fdc
		/* uint8_t + uint16_t + size
Packit 549fdc
		 */
Packit 549fdc
		total_size = 2 + 1 + 2 + priv->name_length;
Packit 549fdc
Packit 549fdc
		/* UINT16: write total size of all names
Packit 549fdc
		 */
Packit 549fdc
		ret =
Packit 549fdc
		    _gnutls_buffer_append_prefix(extdata, 16,
Packit 549fdc
						 total_size - 2);
Packit 549fdc
		if (ret < 0)
Packit 549fdc
			return gnutls_assert_val(ret);
Packit 549fdc
Packit 549fdc
		/* UINT8: type of this extension
Packit 549fdc
		 * UINT16: size of the first name
Packit 549fdc
		 * LEN: the actual server name.
Packit 549fdc
		 */
Packit 549fdc
		ret =
Packit 549fdc
		    _gnutls_buffer_append_prefix(extdata, 8, 0);
Packit 549fdc
		if (ret < 0)
Packit 549fdc
			return gnutls_assert_val(ret);
Packit 549fdc
Packit 549fdc
		_gnutls_debug_log("HSK[%p]: sent server name: '%s'\n", session, priv->name);
Packit 549fdc
Packit 549fdc
		ret =
Packit 549fdc
		    _gnutls_buffer_append_data_prefix
Packit 549fdc
			    (extdata, 16,
Packit 549fdc
			     priv->name, priv->name_length);
Packit 549fdc
		if (ret < 0)
Packit 549fdc
			return gnutls_assert_val(ret);
Packit 549fdc
	} else {
Packit 549fdc
		return 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return total_size;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_server_name_get:
Packit 549fdc
 * @session: is a #gnutls_session_t type.
Packit 549fdc
 * @data: will hold the data
Packit 549fdc
 * @data_length: will hold the data length. Must hold the maximum size of data.
Packit 549fdc
 * @type: will hold the server name indicator type
Packit 549fdc
 * @indx: is the index of the server_name
Packit 549fdc
 *
Packit 549fdc
 * This function will allow you to get the name indication (if any), a
Packit 549fdc
 * client has sent.  The name indication may be any of the enumeration
Packit 549fdc
 * gnutls_server_name_type_t.
Packit 549fdc
 *
Packit 549fdc
 * If @type is GNUTLS_NAME_DNS, then this function is to be used by
Packit 549fdc
 * servers that support virtual hosting, and the data will be a null
Packit 549fdc
 * terminated IDNA ACE string (prior to GnuTLS 3.4.0 it was a UTF-8 string).
Packit 549fdc
 *
Packit 549fdc
 * If @data has not enough size to hold the server name
Packit 549fdc
 * GNUTLS_E_SHORT_MEMORY_BUFFER is returned, and @data_length will
Packit 549fdc
 * hold the required size.
Packit 549fdc
 *
Packit 549fdc
 * @indx is used to retrieve more than one server names (if sent by
Packit 549fdc
 * the client).  The first server name has an index of 0, the second 1
Packit 549fdc
 * and so on.  If no name with the given index exists
Packit 549fdc
 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
Packit 549fdc
 *
Packit 549fdc
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, on UTF-8
Packit 549fdc
 *  decoding error %GNUTLS_E_IDNA_ERROR is returned, otherwise a negative
Packit 549fdc
 *  error code is returned.
Packit 549fdc
 **/
Packit 549fdc
int
Packit 549fdc
gnutls_server_name_get(gnutls_session_t session, void *data,
Packit 549fdc
		       size_t * data_length,
Packit 549fdc
		       unsigned int *type, unsigned int indx)
Packit 549fdc
{
Packit 549fdc
	char *_data = data;
Packit 549fdc
	server_name_ext_st *priv;
Packit 549fdc
	int ret;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	if (session->security_parameters.entity == GNUTLS_CLIENT) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (indx != 0)
Packit 549fdc
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_session_data(session,
Packit 549fdc
					 GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
					 &epriv);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	priv = epriv;
Packit 549fdc
Packit 549fdc
	if (priv->name_length == 0) {
Packit 549fdc
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	*type = priv->type;
Packit 549fdc
Packit 549fdc
	if (*data_length >	/* greater since we need one extra byte for the null */
Packit 549fdc
	    priv->name_length) {
Packit 549fdc
		*data_length = priv->name_length;
Packit 549fdc
		memcpy(data, priv->name, *data_length);
Packit 549fdc
Packit 549fdc
		if (*type == GNUTLS_NAME_DNS)	/* null terminate */
Packit 549fdc
			_data[(*data_length)] = 0;
Packit 549fdc
Packit 549fdc
	} else {
Packit 549fdc
		*data_length = priv->name_length + 1;
Packit 549fdc
		ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret = 0;
Packit 549fdc
 cleanup:
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* This does not do any conversion not perform any check */
Packit 549fdc
int
Packit 549fdc
_gnutls_server_name_set_raw(gnutls_session_t session,
Packit 549fdc
		       gnutls_server_name_type_t type,
Packit 549fdc
		       const void *name, size_t name_length)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	server_name_ext_st *priv;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
	int set = 0;
Packit 549fdc
Packit 549fdc
	if (name_length >= MAX_SERVER_NAME_SIZE) {
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_session_data(session,
Packit 549fdc
					 GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
					 &epriv);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		set = 1;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (set != 0) {
Packit 549fdc
		priv = gnutls_calloc(1, sizeof(*priv));
Packit 549fdc
		if (priv == NULL) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
		}
Packit 549fdc
		epriv = priv;
Packit 549fdc
	} else
Packit 549fdc
		priv = epriv;
Packit 549fdc
Packit 549fdc
	priv->type = type;
Packit 549fdc
Packit 549fdc
	if (name_length > 0) {
Packit 549fdc
		memcpy(priv->name, name, name_length);
Packit 549fdc
		priv->name[name_length] = 0;
Packit 549fdc
	}
Packit 549fdc
	priv->name_length = name_length;
Packit 549fdc
Packit 549fdc
	if (set != 0)
Packit 549fdc
		_gnutls_ext_set_session_data(session,
Packit 549fdc
					     GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
					     epriv);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_server_name_set:
Packit 549fdc
 * @session: is a #gnutls_session_t type.
Packit 549fdc
 * @type: specifies the indicator type
Packit 549fdc
 * @name: is a string that contains the server name.
Packit 549fdc
 * @name_length: holds the length of name excluding the terminating null byte
Packit 549fdc
 *
Packit 549fdc
 * This function is to be used by clients that want to inform (via a
Packit 549fdc
 * TLS extension mechanism) the server of the name they connected to.
Packit 549fdc
 * This should be used by clients that connect to servers that do
Packit 549fdc
 * virtual hosting.
Packit 549fdc
 *
Packit 549fdc
 * The value of @name depends on the @type type.  In case of
Packit 549fdc
 * %GNUTLS_NAME_DNS, a UTF-8 null-terminated domain name string,
Packit 549fdc
 * without the trailing dot, is expected.
Packit 549fdc
 *
Packit 549fdc
 * IPv4 or IPv6 addresses are not permitted to be set by this function.
Packit 549fdc
 * If the function is called with a name of @name_length zero it will clear
Packit 549fdc
 * all server names set.
Packit 549fdc
 *
Packit 549fdc
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
Packit 549fdc
 *   otherwise a negative error code is returned.
Packit 549fdc
 **/
Packit 549fdc
int
Packit 549fdc
gnutls_server_name_set(gnutls_session_t session,
Packit 549fdc
		       gnutls_server_name_type_t type,
Packit 549fdc
		       const void *name, size_t name_length)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	gnutls_datum_t idn_name = {NULL,0};
Packit 549fdc
Packit 549fdc
	if (session->security_parameters.entity == GNUTLS_SERVER) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (name_length == 0) { /* unset extension */
Packit 549fdc
		_gnutls_ext_unset_session_data(session, GNUTLS_EXTENSION_SERVER_NAME);
Packit 549fdc
		return 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret = gnutls_idna_map(name, name_length, &idn_name, 0);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		 _gnutls_debug_log("unable to convert name %s to IDNA2008 format\n", (char*)name);
Packit 549fdc
		 return ret;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	name = idn_name.data;
Packit 549fdc
	name_length = idn_name.size;
Packit 549fdc
Packit 549fdc
	ret = _gnutls_server_name_set_raw(session, type, name, name_length);
Packit 549fdc
	gnutls_free(idn_name.data);
Packit 549fdc
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
static void _gnutls_server_name_deinit_data(gnutls_ext_priv_data_t priv)
Packit 549fdc
{
Packit 549fdc
	gnutls_free(priv);
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
static int
Packit 549fdc
_gnutls_server_name_pack(gnutls_ext_priv_data_t epriv,
Packit 549fdc
			 gnutls_buffer_st * ps)
Packit 549fdc
{
Packit 549fdc
	server_name_ext_st *priv = epriv;
Packit 549fdc
	int ret;
Packit 549fdc
Packit 549fdc
	BUFFER_APPEND_NUM(ps, priv->type);
Packit 549fdc
	BUFFER_APPEND_PFX4(ps, priv->name,
Packit 549fdc
			   priv->name_length);
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
static int
Packit 549fdc
_gnutls_server_name_unpack(gnutls_buffer_st * ps,
Packit 549fdc
			   gnutls_ext_priv_data_t * _priv)
Packit 549fdc
{
Packit 549fdc
	server_name_ext_st *priv;
Packit 549fdc
	int ret;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	priv = gnutls_calloc(1, sizeof(*priv));
Packit 549fdc
	if (priv == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	BUFFER_POP_NUM(ps, priv->type);
Packit 549fdc
	BUFFER_POP_NUM(ps, priv->name_length);
Packit 549fdc
	if (priv->name_length >=
Packit 549fdc
	    sizeof(priv->name)) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_PARSING_ERROR;
Packit 549fdc
	}
Packit 549fdc
	BUFFER_POP(ps, priv->name,
Packit 549fdc
		   priv->name_length);
Packit 549fdc
	priv->name[priv->name_length] = 0;
Packit 549fdc
Packit 549fdc
	epriv = priv;
Packit 549fdc
	*_priv = epriv;
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
      error:
Packit 549fdc
	gnutls_free(priv);
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
unsigned _gnutls_server_name_matches_resumed(gnutls_session_t session)
Packit 549fdc
{
Packit 549fdc
	server_name_ext_st *priv1, *priv2;
Packit 549fdc
	int ret;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_session_data(session,
Packit 549fdc
					 GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
					 &epriv);
Packit 549fdc
	if (ret < 0) /* no server name in this session */
Packit 549fdc
		priv1 = NULL;
Packit 549fdc
	else
Packit 549fdc
		priv1 = epriv;
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_resumed_session_data(session,
Packit 549fdc
						 GNUTLS_EXTENSION_SERVER_NAME,
Packit 549fdc
						 &epriv);
Packit 549fdc
	if (ret < 0) /* no server name in extensions */
Packit 549fdc
		priv2 = NULL;
Packit 549fdc
	else
Packit 549fdc
		priv2 = epriv;
Packit 549fdc
Packit 549fdc
	if (priv1 == NULL || priv2 == NULL) {
Packit 549fdc
		if (priv1 == priv2)
Packit 549fdc
			return 1;
Packit 549fdc
		else
Packit 549fdc
			return 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (priv1->name_length != priv2->name_length)
Packit 549fdc
		return 0;
Packit 549fdc
Packit 549fdc
	if (memcmp(priv1->name, priv2->name, priv1->name_length) != 0)
Packit 549fdc
		return 0;
Packit 549fdc
Packit 549fdc
	return 1;
Packit 549fdc
}