extern int fr_isbase64 (char ch);
-extern void fr_base64_encode (const char *in, size_t inlen,
+extern void fr_base64_encode (const uint8_t *in, size_t inlen,
char *out, size_t outlen);
-extern size_t fr_base64_encode_alloc (const char *in, size_t inlen, char **out);
+extern size_t fr_base64_encode_alloc (const uint8_t *in, size_t inlen, char **out);
extern int fr_base64_decode (const char *in, size_t inlen,
char *out, size_t *outlen);
VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
const char *secret, int attribute, int length,
const uint8_t *data);
+ssize_t rad_vp2data(const VALUE_PAIR *vp, uint8_t *out, size_t outlen);
int rad_vp2attr(const RADIUS_PACKET *packet,
const RADIUS_PACKET *original, const char *secret,
const VALUE_PAIR *vp, uint8_t *ptr);
If OUTLEN is less than FR_BASE64_ENC_LENGTH(INLEN), write as many bytes as
possible. If OUTLEN is larger than FR_BASE64_ENC_LENGTH(INLEN), also zero
terminate the output buffer. */
-void fr_base64_encode (const char *in, size_t inlen,
+void fr_base64_encode (const uint8_t *in, size_t inlen,
char *out, size_t outlen)
{
static const char b64str[64] =
while (inlen && outlen)
{
- *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
+ *out++ = b64str[(in[0] >> 2) & 0x3f];
if (!--outlen)
break;
- *out++ = b64str[((to_uchar (in[0]) << 4)
- + (--inlen ? to_uchar (in[1]) >> 4 : 0))
+ *out++ = b64str[((in[0] << 4)
+ + (--inlen ? in[1] >> 4 : 0))
& 0x3f];
if (!--outlen)
break;
*out++ =
(inlen
- ? b64str[((to_uchar (in[1]) << 2)
- + (--inlen ? to_uchar (in[2]) >> 6 : 0))
+ ? b64str[((in[1] << 2)
+ + (--inlen ? in[2] >> 6 : 0))
& 0x3f]
: '=');
if (!--outlen)
break;
- *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
+ *out++ = inlen ? b64str[in[2] & 0x3f] : '=';
if (!--outlen)
break;
if (inlen)
indicates length of the requested memory block, i.e.,
FR_BASE64_ENC_LENGTH(inlen) + 1. */
size_t
-fr_base64_encode_alloc (const char *in, size_t inlen, char **out)
+fr_base64_encode_alloc (const uint8_t *in, size_t inlen, char **out)
{
size_t outlen = 1 + FR_BASE64_ENC_LENGTH (inlen);
return data2vp(packet, original, secret, attribute, length, data, vp);
}
+/**
+ * Converts vp_data to network byte order
+ * Returns:
+ * -1 on error, or the length of the value
+ */
+ssize_t rad_vp2data(const VALUE_PAIR *vp, uint8_t *out, size_t outlen)
+{
+ size_t len = 0;
+ uint32_t lvalue;
+
+ len = vp->length;
+ if (outlen < len) {
+ fr_strerror_printf("ERROR: rad_vp2data buffer passed too small");
+ return -1;
+ }
+
+ switch(vp->type) {
+ case PW_TYPE_STRING:
+ case PW_TYPE_OCTETS:
+ case PW_TYPE_IFID:
+ case PW_TYPE_IPADDR:
+ case PW_TYPE_IPV6ADDR:
+ case PW_TYPE_IPV6PREFIX:
+ case PW_TYPE_ABINARY:
+ case PW_TYPE_TLV:
+ memcpy(out, vp->vp_octets, len);
+ break;
+ case PW_TYPE_BYTE:
+ out[0] = vp->vp_integer & 0xff;
+ break;
+
+ case PW_TYPE_SHORT:
+ out[0] = (vp->vp_integer >> 8) & 0xff;
+ out[1] = vp->vp_integer & 0xff;
+ break;
+
+ case PW_TYPE_INTEGER:
+ lvalue = htonl(vp->vp_integer);
+ memcpy(out, &lvalue, sizeof(lvalue));
+ break;
+
+ case PW_TYPE_DATE:
+ lvalue = htonl(vp->vp_date);
+ memcpy(out, &lvalue, sizeof(lvalue));
+ break;
+
+ case PW_TYPE_SIGNED:
+ {
+ int32_t slvalue;
+
+ slvalue = htonl(vp->vp_signed);
+ memcpy(out, &slvalue, sizeof(slvalue));
+ break;
+ }
+ /* unknown type: ignore it */
+ default:
+ fr_strerror_printf("ERROR: Unknown attribute type %d",
+ vp->type);
+ return -1;
+ }
+
+ return len;
+}
/*
* Calculate/check digest, and decode radius attributes.
UNUSED RADIUS_ESCAPE_STRING func)
{
size_t i;
- uint8_t *p;
VALUE_PAIR *vp;
+ uint8_t buffer[MAX_STRING_LEN];
+ ssize_t ret;
+ size_t len;
while (isspace((int) *fmt)) fmt++;
*out = '\0';
return 0;
}
-
+
+ ret = rad_vp2data(vp, buffer, sizeof(buffer));
+ len = (size_t) ret;
+
/*
* Don't truncate the data.
*/
- if (outlen < (vp->length * 2)) {
+ if ((ret < 0 ) || (outlen < (len * 2))) {
*out = 0;
return 0;
}
- p = &vp->vp_octets[0];
- for (i = 0; i < vp->length; i++) {
- snprintf(out + 2*i, 3, "%02x", p[i]);
+ for (i = 0; i < len; i++) {
+ snprintf(out + 2*i, 3, "%02x", buffer[i]);
}
- return vp->length * 2;
+ return len * 2;
}
/**
const char *fmt, char *out, size_t outlen)
{
VALUE_PAIR *vp;
- size_t len;
+ uint8_t buffer[MAX_STRING_LEN];
+ ssize_t ret;
+ size_t len;
+ size_t enc;
while (isspace((int) *fmt)) fmt++;
return 0;
}
- len = FR_BASE64_ENC_LENGTH(vp->length);
+ ret = rad_vp2data(vp, buffer, sizeof(buffer));
+ if (ret < 0) {
+ *out = 0;
+ return 0;
+ }
+
+ len = (size_t) ret;
+
+ enc = FR_BASE64_ENC_LENGTH(len);
/*
* Don't truncate the data.
*/
- if (outlen < (len + 1)) {
+ if (outlen < (enc + 1)) {
*out = 0;
return 0;
}
- fr_base64_encode((char *) vp->vp_octets, vp->length, out, outlen);
+ fr_base64_encode(buffer, len, out, outlen);
- return len;
+ return enc;
}
#ifdef HAVE_REGEX_H