コード例 #1
0
ファイル: radius.c プロジェクト: sevennothing/lros
struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
					    const u8 *data, size_t data_len)
{
	size_t buf_needed;
	struct radius_attr_hdr *attr;

	if (data_len > RADIUS_MAX_ATTR_LEN) {
		printf("radius_msg_add_attr: too long attribute (%lu bytes)\n",
		       (unsigned long) data_len);
		return NULL;
	}

	buf_needed = sizeof(*attr) + data_len;

	if (wpabuf_tailroom(msg->buf) < buf_needed) {
		/* allocate more space for message buffer */
		if (wpabuf_resize(&msg->buf, buf_needed) < 0)
			return NULL;
		msg->hdr = wpabuf_mhead(msg->buf);
	}

	attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
	attr->type = type;
	attr->length = sizeof(*attr) + data_len;
	wpabuf_put_data(msg->buf, data, data_len);

	if (radius_msg_add_attr_to_array(msg, attr))
		return NULL;

	return attr;
}
コード例 #2
0
ファイル: radius.c プロジェクト: KHATEEBNSIT/AP
struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
					    const u8 *data, size_t data_len)
{
	size_t buf_needed;
	struct radius_attr_hdr *attr;

	if (data_len > RADIUS_MAX_ATTR_LEN) {
		printf("radius_msg_add_attr: too long attribute (%lu bytes)\n",
		       (unsigned long) data_len);
		return NULL;
	}

	buf_needed = msg->buf_used + sizeof(*attr) + data_len;

	if (msg->buf_size < buf_needed) {
		/* allocate more space for message buffer */
		unsigned char *nbuf;
		size_t i, nlen = msg->buf_size;
		int diff;

		while (nlen < buf_needed)
			nlen *= 2;
		nbuf = os_realloc(msg->buf, nlen);
		if (nbuf == NULL)
			return NULL;
		diff = nbuf - msg->buf;
		msg->buf = nbuf;
		msg->hdr = (struct radius_hdr *) msg->buf;
		/* adjust attr pointers to match with the new buffer */
		for (i = 0; i < msg->attr_used; i++)
			msg->attrs[i] = (struct radius_attr_hdr *)
				(((u8 *) msg->attrs[i]) + diff);
		os_memset(msg->buf + msg->buf_size, 0, nlen - msg->buf_size);
		msg->buf_size = nlen;
	}

	attr = (struct radius_attr_hdr *) (msg->buf + msg->buf_used);
	attr->type = type;
	attr->length = sizeof(*attr) + data_len;
	if (data_len > 0)
		os_memcpy(attr + 1, data, data_len);

	msg->buf_used += sizeof(*attr) + data_len;

	if (radius_msg_add_attr_to_array(msg, attr))
		return NULL;

	return attr;
}
コード例 #3
0
ファイル: radius.c プロジェクト: ClearwaterCore/freeDiameter
struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
					    const u8 *data, size_t data_len)
{
	size_t buf_needed;
	struct radius_attr_hdr *attr;

	if (data_len > RADIUS_MAX_ATTR_LEN) {
		fd_log_debug("radius_msg_add_attr: too long attribute (%lu bytes)",
		       (unsigned long) data_len);
		return NULL;
	}

	buf_needed = msg->buf_used + sizeof(*attr) + data_len;

	if (msg->buf_size < buf_needed) {
		/* allocate more space for message buffer */
		unsigned char *nbuf;
		size_t nlen = msg->buf_size;

		while (nlen < buf_needed)
			nlen *= 2;
		nbuf = os_realloc(msg->buf, nlen);
		if (nbuf == NULL)
			return NULL;
		msg->buf = nbuf;
		msg->hdr = (struct radius_hdr *) msg->buf;
		os_memset(msg->buf + msg->buf_size, 0, nlen - msg->buf_size);
		msg->buf_size = nlen;
	}

	attr = (struct radius_attr_hdr *) (msg->buf + msg->buf_used);
	attr->type = type;
	attr->length = sizeof(*attr) + data_len;
	if (data_len > 0)
		os_memcpy(attr + 1, data, data_len);

	msg->buf_used += sizeof(*attr) + data_len;

	if (radius_msg_add_attr_to_array(msg, attr))
		return NULL;

	return attr;
}
コード例 #4
0
ファイル: radius.c プロジェクト: KHATEEBNSIT/AP
struct radius_msg *radius_msg_parse(const u8 *data, size_t len)
{
	struct radius_msg *msg;
	struct radius_hdr *hdr;
	struct radius_attr_hdr *attr;
	size_t msg_len;
	unsigned char *pos, *end;

	if (data == NULL || len < sizeof(*hdr))
		return NULL;

	hdr = (struct radius_hdr *) data;

	msg_len = ntohs(hdr->length);
	if (msg_len < sizeof(*hdr) || msg_len > len) {
		printf("Invalid RADIUS message length\n");
		return NULL;
	}

	if (msg_len < len) {
		printf("Ignored %lu extra bytes after RADIUS message\n",
		       (unsigned long) len - msg_len);
	}

	msg = os_malloc(sizeof(*msg));
	if (msg == NULL)
		return NULL;

	if (radius_msg_initialize(msg, msg_len)) {
		os_free(msg);
		return NULL;
	}

	os_memcpy(msg->buf, data, msg_len);
	msg->buf_size = msg->buf_used = msg_len;

	/* parse attributes */
	pos = (unsigned char *) (msg->hdr + 1);
	end = msg->buf + msg->buf_used;
	while (pos < end) {
		if ((size_t) (end - pos) < sizeof(*attr))
			goto fail;

		attr = (struct radius_attr_hdr *) pos;

		if (pos + attr->length > end || attr->length < sizeof(*attr))
			goto fail;

		/* TODO: check that attr->length is suitable for attr->type */

		if (radius_msg_add_attr_to_array(msg, attr))
			goto fail;

		pos += attr->length;
	}

	return msg;

 fail:
	radius_msg_free(msg);
	os_free(msg);
	return NULL;
}
コード例 #5
0
ファイル: radius.c プロジェクト: sevennothing/lros
/**
 * radius_msg_parse - Parse a RADIUS message
 * @data: RADIUS message to be parsed
 * @len: Length of data buffer in octets
 * Returns: Parsed RADIUS message or %NULL on failure
 *
 * This parses a RADIUS message and makes a copy of its data. The caller is
 * responsible for freeing the returned data with radius_msg_free().
 */
struct radius_msg * radius_msg_parse(const u8 *data, size_t len)
{
	struct radius_msg *msg;
	struct radius_hdr *hdr;
	struct radius_attr_hdr *attr;
	size_t msg_len;
	unsigned char *pos, *end;

	if (data == NULL || len < sizeof(*hdr))
		return NULL;

	hdr = (struct radius_hdr *) data;

	msg_len = ntohs(hdr->length);
	if (msg_len < sizeof(*hdr) || msg_len > len) {
		wpa_printf(MSG_INFO, "RADIUS: Invalid message length");
		return NULL;
	}

	if (msg_len < len) {
		wpa_printf(MSG_DEBUG, "RADIUS: Ignored %lu extra bytes after "
			   "RADIUS message", (unsigned long) len - msg_len);
	}

	msg = os_zalloc(sizeof(*msg));
	if (msg == NULL)
		return NULL;

	msg->buf = wpabuf_alloc_copy(data, msg_len);
	if (msg->buf == NULL || radius_msg_initialize(msg)) {
		radius_msg_free(msg);
		return NULL;
	}
	msg->hdr = wpabuf_mhead(msg->buf);

	/* parse attributes */
	pos = wpabuf_mhead_u8(msg->buf) + sizeof(struct radius_hdr);
	end = wpabuf_mhead_u8(msg->buf) + wpabuf_len(msg->buf);
	while (pos < end) {
		if ((size_t) (end - pos) < sizeof(*attr))
			goto fail;

		attr = (struct radius_attr_hdr *) pos;

		if (pos + attr->length > end || attr->length < sizeof(*attr))
			goto fail;

		/* TODO: check that attr->length is suitable for attr->type */

		if (radius_msg_add_attr_to_array(msg, attr))
			goto fail;

		pos += attr->length;
	}

	return msg;

 fail:
	radius_msg_free(msg);
	return NULL;
}
コード例 #6
0
ファイル: radius.c プロジェクト: ClearwaterCore/freeDiameter
/* Modified version of radius_msg_parse */
int rgw_msg_parse(unsigned char * buf, size_t len, struct rgw_radius_msg_meta ** msg)
{
	struct rgw_radius_msg_meta * temp_msg = NULL;
	struct radius_hdr *hdr;
	struct radius_attr_hdr *attr;
	size_t msg_len;
	unsigned char *pos, *end;
	int ret = 0;
	
	TRACE_ENTRY("%p %zd %p", buf, len, msg);
	
	CHECK_PARAMS( buf && len >= sizeof(*hdr) && msg );
	
	*msg = NULL;
	
	/* Parse the RADIUS message */
	hdr = (struct radius_hdr *) buf;
	msg_len = ntohs(hdr->length);
	if (msg_len < sizeof(*hdr) || msg_len > len) {
		TRACE_DEBUG(INFO, "Invalid RADIUS message length");
		return EINVAL;
	}

	if (msg_len < len) {
		TRACE_DEBUG(INFO, "Ignored %lu extra bytes after RADIUS message",
		       (unsigned long) len - msg_len);
	}

	CHECK_MALLOC( temp_msg = malloc(sizeof(struct rgw_radius_msg_meta)) );
	memset(temp_msg, 0, sizeof(struct rgw_radius_msg_meta));
	
	if (radius_msg_initialize(&temp_msg->radius, msg_len)) {
		TRACE_DEBUG(INFO, "Error in radius_msg_initialize, returning ENOMEM.");
		free(temp_msg);
		return ENOMEM;
	}
	
	/* Store the received data in the alloc'd buffer */
	memcpy(temp_msg->radius.buf, buf, msg_len);
	temp_msg->radius.buf_size = temp_msg->radius.buf_used = msg_len;
	
	/* parse attributes */
	pos = (unsigned char *) (temp_msg->radius.hdr + 1);
	end = temp_msg->radius.buf + temp_msg->radius.buf_used;
	
	while (pos < end) {
		if ((size_t) (end - pos) < sizeof(*attr)) {
			TRACE_DEBUG(INFO, "Trucated attribute found in RADIUS buffer, EINVAL.");
			ret = EINVAL;
			break;
		}
			
		attr = (struct radius_attr_hdr *) pos;
	
		if (pos + attr->length > end || attr->length < sizeof(*attr)) {
			TRACE_DEBUG(INFO, "Trucated attribute found in RADIUS buffer, EINVAL.");
			ret = EINVAL;
			break;
		}

		if (radius_msg_add_attr_to_array(&temp_msg->radius, attr)) {
			TRACE_DEBUG(INFO, "Error in radius_msg_add_attr_to_array, ENOMEM");
			ret = ENOMEM;
			break;
		}
		
		if (attr->type == RADIUS_ATTR_PROXY_STATE)
			temp_msg->ps_nb += 1;

		pos += attr->length;
	}
	
	if (ret != 0) {
		radius_msg_free(&temp_msg->radius);
		free(temp_msg);
		return ret;
	}
	
	/* Now move all the proxy-state attributes at the end of the attr_pos array */
	if (temp_msg->ps_nb) {
		size_t *temp_ps = NULL;
		int n, new_n = 0, p = 0;
		
		CHECK_MALLOC( temp_ps = calloc(temp_msg->ps_nb, sizeof(size_t)) );
		
		/* Move all the Proxy-State attributes into the temp_ps array */
		for (n=0; n < temp_msg->radius.attr_used; n++) {
			struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(temp_msg->radius.buf + temp_msg->radius.attr_pos[n]);
			
			if (attr->type == RADIUS_ATTR_PROXY_STATE) {
				temp_ps[p++] = temp_msg->radius.attr_pos[n];
			} else {
				temp_msg->radius.attr_pos[new_n++] = temp_msg->radius.attr_pos[n];
			}
		}
		temp_msg->radius.attr_used = new_n; /* hide the proxy-state to other modules */
		temp_msg->ps_first = new_n;
		
		/* And back into the array */
		memcpy(temp_msg->radius.attr_pos + new_n, temp_ps, p * sizeof(size_t));
		free(temp_ps);
	}
	
	*msg = temp_msg;
	return 0;
}