static void perl_vp_to_svpvn_element(REQUEST *request, AV *av, VALUE_PAIR const *vp,
				     int *i, const char *hash_name, const char *list_name)
{
	size_t len;

	char buffer[1024];

	switch (vp->da->type) {
	case PW_TYPE_STRING:
		RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
		       list_name, vp->da->name, vp->vp_strvalue);
		av_push(av, newSVpvn(vp->vp_strvalue, vp->vp_length));
		break;

	case PW_TYPE_OCTETS:
		if (RDEBUG_ENABLED) {
			char *hex;

			hex = fr_abin2hex(request, vp->vp_octets, vp->vp_length);
			RDEBUG("$%s{'%s'}[%i] = &%s:%s -> 0x%s", hash_name, vp->da->name, *i,
			       list_name, vp->da->name, hex);
			talloc_free(hex);
		}
		av_push(av, newSVpvn((char const *)vp->vp_octets, vp->vp_length));
		break;

	default:
		len = fr_pair_value_snprint(buffer, sizeof(buffer), vp, 0);
		RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
		       list_name, vp->da->name, buffer);
		av_push(av, newSVpvn(buffer, truncate_len(len, sizeof(buffer))));
		break;
	}
	(*i)++;
}
Beispiel #2
0
static void perl_vp_to_svpvn_element(REQUEST *request, AV *av, VALUE_PAIR const *vp,
				     int *i, const char *hash_name, const char *list_name)
{
	size_t len;
	SV *sv;
	char buffer[1024];


	switch (vp->da->type) {
	case PW_TYPE_STRING:
		RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
		       list_name, vp->da->name, vp->vp_strvalue);
		sv = newSVpvn(vp->vp_strvalue, vp->vp_length);
		break;

	default:
		len = vp_prints_value(buffer, sizeof(buffer), vp, 0);
		RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
		       list_name, vp->da->name, buffer);
		sv = newSVpvn(buffer, truncate_len(len, sizeof(buffer)));
		break;
	}

	if (!sv) return;
	SvTAINTED_on(sv);
	av_push(av, sv);
	(*i)++;
}
Beispiel #3
0
static void perl_vp_to_svpvn_element(REQUEST *request, AV *av, VALUE_PAIR const *vp,
				     int *i, const char *hash_name, const char *list_name)
{

	SV *sv;

	switch (vp->vp_type) {
	case FR_TYPE_STRING:
		RDEBUG2("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
		        list_name, vp->da->name, vp->vp_strvalue);
		sv = newSVpvn(vp->vp_strvalue, vp->vp_length);
		break;

	case FR_TYPE_OCTETS:
		RDEBUG2("$%s{'%s'}[%i] = &%s:%s -> 0x%pH", hash_name, vp->da->name, *i,
		        list_name, vp->da->name, &vp->data);
		sv = newSVpvn((char const *)vp->vp_octets, vp->vp_length);
		break;

	default:
	{
		char	buffer[1024];
		size_t	len;

		len = fr_pair_value_snprint(buffer, sizeof(buffer), vp, '\0');
		RDEBUG2("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
		        list_name, vp->da->name, buffer);
		sv = newSVpvn(buffer, truncate_len(len, sizeof(buffer)));
	}
		break;
	}

	if (!sv) return;
	SvTAINT(sv);
	av_push(av, sv);
	(*i)++;
}
Beispiel #4
0
/*
 *  	get the vps and put them in perl hash
 *  	If one VP have multiple values it is added as array_ref
 *  	Example for this is Cisco-AVPair that holds multiple values.
 *  	Which will be available as array_ref in $RAD_REQUEST{'Cisco-AVPair'}
 */
static void perl_store_vps(UNUSED TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vps, HV *rad_hv,
			   const char *hash_name, const char *list_name)
{
	VALUE_PAIR *vp;

	hv_undef(rad_hv);

	fr_cursor_t cursor;

	RINDENT();
	fr_pair_list_sort(vps, fr_pair_cmp_by_da_tag);
	for (vp = fr_cursor_init(&cursor, vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		VALUE_PAIR *next;

		char const *name;
		char namebuf[256];

		/*
		 *	Tagged attributes are added to the hash with name
		 *	<attribute>:<tag>, others just use the normal attribute
		 *	name as the key.
		 */
		if (vp->da->flags.has_tag && (vp->tag != TAG_ANY)) {
			snprintf(namebuf, sizeof(namebuf), "%s:%d", vp->da->name, vp->tag);
			name = namebuf;
		} else {
			name = vp->da->name;
		}

		/*
		 *	We've sorted by type, then tag, so attributes of the
		 *	same type/tag should follow on from each other.
		 */
		if ((next = fr_cursor_next_peek(&cursor)) && ATTRIBUTE_EQ(vp, next)) {
			int i = 0;
			AV *av;

			av = newAV();
			perl_vp_to_svpvn_element(request, av, vp, &i, hash_name, list_name);
			do {
				perl_vp_to_svpvn_element(request, av, next, &i, hash_name, list_name);
				fr_cursor_next(&cursor);
			} while ((next = fr_cursor_next_peek(&cursor)) && ATTRIBUTE_EQ(vp, next));
			(void)hv_store(rad_hv, name, strlen(name), newRV_noinc((SV *)av), 0);

			continue;
		}

		/*
		 *	It's a normal single valued attribute
		 */
		switch (vp->vp_type) {
		case FR_TYPE_STRING:
			RDEBUG2("$%s{'%s'} = &%s:%s -> '%pV'", hash_name, vp->da->name, list_name,
			       vp->da->name, &vp->data);
			(void)hv_store(rad_hv, name, strlen(name), newSVpvn(vp->vp_strvalue, vp->vp_length), 0);
			break;

		case FR_TYPE_OCTETS:
			RDEBUG2("$%s{'%s'} = &%s:%s -> %pV", hash_name, vp->da->name, list_name,
			       vp->da->name, &vp->data);
			(void)hv_store(rad_hv, name, strlen(name),
				       newSVpvn((char const *)vp->vp_octets, vp->vp_length), 0);
			break;

		default:
		{
			char buffer[1024];
			size_t len;

			len = fr_pair_value_snprint(buffer, sizeof(buffer), vp, '\0');
			RDEBUG2("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name,
			       list_name, vp->da->name, buffer);
			(void)hv_store(rad_hv, name, strlen(name),
				       newSVpvn(buffer, truncate_len(len, sizeof(buffer))), 0);
		}
			break;
		}
	}
	REXDENT();
}
Beispiel #5
0
/*
 *  	get the vps and put them in perl hash
 *  	If one VP have multiple values it is added as array_ref
 *  	Example for this is Cisco-AVPair that holds multiple values.
 *  	Which will be available as array_ref in $RAD_REQUEST{'Cisco-AVPair'}
 */
static void perl_store_vps(UNUSED TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR *vps, HV *rad_hv,
			   const char *hashname, const char *list_name)
{
	VALUE_PAIR *vp;

	hv_undef(rad_hv);

	vp_cursor_t cursor;

	RINDENT();
	pairsort(&vps, attrtagcmp);
	for (vp = fr_cursor_init(&cursor, &vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		VALUE_PAIR *next;

		char const *name;
		char namebuf[256];
		char buffer[1024];

		size_t len;

		/*
		 *	Tagged attributes are added to the hash with name
		 *	<attribute>:<tag>, others just use the normal attribute
		 *	name as the key.
		 */
		if (vp->da->flags.has_tag && (vp->tag != TAG_ANY)) {
			snprintf(namebuf, sizeof(namebuf), "%s:%d", vp->da->name, vp->tag);
			name = namebuf;
		} else {
			name = vp->da->name;
		}

		/*
		 *	We've sorted by type, then tag, so attributes of the
		 *	same type/tag should follow on from each other.
		 */
		if ((next = fr_cursor_next_peek(&cursor)) && ATTRIBUTE_EQ(vp, next)) {
			int i;
			AV *av;

			av = newAV();
			for (next = fr_cursor_next_by_da(&cursor, vp->da, vp->tag), i = 0;
			     next;
			     next = fr_cursor_next_by_da(&cursor, vp->da, vp->tag), i++) {
				switch (vp->da->type) {
				case PW_TYPE_STRING:
					RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hashname, next->da->name, i,
					       list_name, next->da->name, next->vp_strvalue);
					av_push(av, newSVpvn(next->vp_strvalue, next->length));
					break;

				case PW_TYPE_OCTETS:
					if (RDEBUG_ENABLED) {
						char *hex;

						hex = fr_abin2hex(request, next->vp_octets, next->length);
						RDEBUG("$%s{'%s'}[%i] = &%s:%s -> 0x%s", hashname, next->da->name, i,
						       list_name, next->da->name, hex);
						talloc_free(hex);
					}
					av_push(av, newSVpvn((char const *)next->vp_octets, next->length));
					break;

				default:
					len = vp_prints_value(buffer, sizeof(buffer), next, 0);
					RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hashname, next->da->name, i,
					       list_name, next->da->name, buffer);
					av_push(av, newSVpvn(buffer, truncate_len(len, sizeof(buffer))));
					break;
				}
			}
			(void)hv_store(rad_hv, name, strlen(name), newRV_noinc((SV *)av), 0);

			continue;
		}

		/*
		 *	It's a normal single valued attribute
		 */
		switch (vp->da->type) {
		case PW_TYPE_STRING:
			RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hashname, vp->da->name, list_name,
			       vp->da->name, vp->vp_strvalue);
			(void)hv_store(rad_hv, name, strlen(name), newSVpvn(vp->vp_strvalue, vp->length), 0);
			break;

		case PW_TYPE_OCTETS:
			if (RDEBUG_ENABLED) {
				char *hex;

				hex = fr_abin2hex(request, vp->vp_octets, vp->length);
				RDEBUG("$%s{'%s'} = &%s:%s -> 0x%s", hashname, vp->da->name,
				       list_name, vp->da->name, hex);
				talloc_free(hex);
			}
			(void)hv_store(rad_hv, name, strlen(name),
				       newSVpvn((char const *)vp->vp_octets, vp->length), 0);
			break;

		default:
			len = vp_prints_value(buffer, sizeof(buffer), vp, 0);
			RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hashname, vp->da->name,
			       list_name, vp->da->name, buffer);
			(void)hv_store(rad_hv, name, strlen(name),
				       newSVpvn(buffer, truncate_len(len, sizeof(buffer))), 0);
			break;
		}
	}
	REXDENT();
}
Beispiel #6
0
/*
 *  	get the vps and put them in perl hash
 *  	If one VP have multiple values it is added as array_ref
 *  	Example for this is Cisco-AVPair that holds multiple values.
 *  	Which will be available as array_ref in $RAD_REQUEST{'Cisco-AVPair'}
 */
static void perl_store_vps(UNUSED TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vps, HV *rad_hv,
			   const char *hash_name, const char *list_name)
{
	VALUE_PAIR *vp;
	char *tbuff;
	size_t tbufflen = 1024;

	hv_undef(rad_hv);

	vp_cursor_t cursor;

	/*
	 *	Find out how much room to allocate.
	 */
	for (vp = fr_cursor_init(&cursor, vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		if (((vp->length * 2) + 3) > tbufflen) {
			tbufflen = (vp->vp_length * 2) + 3;
		}
	}
	tbuff = talloc_array(request, char, tbufflen);

	RINDENT();
	fr_pair_list_sort(vps, fr_pair_cmp_by_da_tag);
	for (vp = fr_cursor_init(&cursor, vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
	     	VALUE_PAIR *next;
	     	char const *name;
		size_t len;
		char namebuf[256];

		/*
		 *	Tagged attributes are added to the hash with name
		 *	<attribute>:<tag>, others just use the normal attribute
		 *	name as the key.
		 */
		if (vp->da->flags.has_tag && (vp->tag != TAG_ANY)) {
			snprintf(namebuf, sizeof(namebuf), "%s:%d", vp->da->name, vp->tag);
			name = namebuf;
		} else {
			name = vp->da->name;
		}

		/*
		 *	We've sorted by type, then tag, so attributes of the
		 *	same type/tag should follow on from each other.
		 */
		if ((next = fr_cursor_next_peek(&cursor)) && ATTRIBUTE_EQ(vp, next)) {
			int i = 0;
			AV *av;

			av = newAV();

			perl_vp_to_svpvn_element(request, av, vp, &i, hash_name, list_name);
			do {
				perl_vp_to_svpvn_element(request, av, next, &i, hash_name, list_name);
				fr_cursor_next(&cursor);
			} while ((next = fr_cursor_next_peek(&cursor)) && ATTRIBUTE_EQ(vp, next));
			(void)hv_store(rad_hv, name, strlen(name), newRV_noinc((SV *)av), 0);

			continue;
		}

		/*
		 *	It's a normal single valued attribute
		 */
		switch (vp->da->type) {
		case PW_TYPE_STRING:
			RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name, list_name,
			       vp->da->name, vp->vp_strvalue);
			(void)hv_store(rad_hv, name, strlen(name), newSVpvn(vp->vp_strvalue, vp->vp_length), 0);
			break;

		default:
			len = vp_prints_value(tbuff, tbufflen, vp, 0);
			RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name,
			       list_name, vp->da->name, tbuff);
			(void)hv_store(rad_hv, name, strlen(name),
				       newSVpvn(tbuff, truncate_len(len, tbufflen)), 0);
			break;
		}
	}
	REXDENT();

	talloc_free(tbuff);
}