added some functions to handle extended attributes in radmsg.c
This commit is contained in:
parent
94e4cb6d4f
commit
5baf471e07
@ -57,14 +57,19 @@ typedef enum qse_rad_code_t qse_rad_code_t;
|
|||||||
|
|
||||||
#define QSE_RAD_MAX_AUTHENTICATOR_LEN 16
|
#define QSE_RAD_MAX_AUTHENTICATOR_LEN 16
|
||||||
#define QSE_RAD_MAX_ATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_attr_hdr_t))
|
#define QSE_RAD_MAX_ATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_attr_hdr_t))
|
||||||
#define QSE_RAD_MAX_VSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_attr_hdr_t) - QSE_SIZEOF(qse_rad_vsattr_hdr_t))
|
#define QSE_RAD_MAX_XATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_xattr_hdr_t))
|
||||||
#define QSE_RAD_MAX_EXTVSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_extvsattr_hdr_t))
|
#define QSE_RAD_MAX_LXATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_lxattr_hdr_t))
|
||||||
|
#define QSE_RAD_MAX_VSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_vsattr_hdr_t))
|
||||||
|
#define QSE_RAD_MAX_XVSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_xvsattr_hdr_t))
|
||||||
|
#define QSE_RAD_MAX_LXVSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_lxvsattr_hdr_t))
|
||||||
|
|
||||||
typedef struct qse_rad_hdr_t qse_rad_hdr_t;
|
typedef struct qse_rad_hdr_t qse_rad_hdr_t;
|
||||||
typedef struct qse_rad_attr_hdr_t qse_rad_attr_hdr_t;
|
typedef struct qse_rad_attr_hdr_t qse_rad_attr_hdr_t;
|
||||||
|
typedef struct qse_rad_xattr_hdr_t qse_rad_xattr_hdr_t;
|
||||||
|
typedef struct qse_rad_lxattr_hdr_t qse_rad_lxattr_hdr_t;
|
||||||
typedef struct qse_rad_vsattr_hdr_t qse_rad_vsattr_hdr_t;
|
typedef struct qse_rad_vsattr_hdr_t qse_rad_vsattr_hdr_t;
|
||||||
typedef struct qse_rad_extvsattr_hdr_t qse_rad_extvsattr_hdr_t; /* evs */
|
typedef struct qse_rad_xvsattr_hdr_t qse_rad_xvsattr_hdr_t;
|
||||||
|
typedef struct qse_rad_lxvsattr_hdr_t qse_rad_lxvsattr_hdr_t; /* evs */
|
||||||
|
|
||||||
typedef struct qse_rad_attr_uint32_t qse_rad_attr_uint32_t;
|
typedef struct qse_rad_attr_uint32_t qse_rad_attr_uint32_t;
|
||||||
#if (QSE_SIZEOF_UINT64_T > 0)
|
#if (QSE_SIZEOF_UINT64_T > 0)
|
||||||
@ -82,24 +87,61 @@ struct qse_rad_hdr_t
|
|||||||
|
|
||||||
struct qse_rad_attr_hdr_t
|
struct qse_rad_attr_hdr_t
|
||||||
{
|
{
|
||||||
qse_uint8_t id; /* qse_rad_attr_id_t */
|
qse_uint8_t type; /* qse_rad_attr_type_t */
|
||||||
qse_uint8_t length;
|
qse_uint8_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct qse_rad_xattr_hdr_t
|
||||||
|
{
|
||||||
|
qse_uint8_t type; /* qse_rad_attr_type_t - one of 241-244 */
|
||||||
|
qse_uint8_t length;
|
||||||
|
qse_uint8_t xtype; /* extended type */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct qse_rad_lxattr_hdr_t
|
||||||
|
{
|
||||||
|
qse_uint8_t type; /* qse_rad_attr_type_t - 245 or 256*/
|
||||||
|
qse_uint8_t length;
|
||||||
|
|
||||||
|
qse_uint8_t xtype; /* extended type */
|
||||||
|
qse_uint8_t xflags; /* bit 7: continuation, bit 6-0: reserved. */
|
||||||
|
};
|
||||||
|
|
||||||
struct qse_rad_vsattr_hdr_t
|
struct qse_rad_vsattr_hdr_t
|
||||||
{
|
{
|
||||||
qse_uint8_t id; /* type */
|
qse_uint8_t type; /* type - 26 */
|
||||||
qse_uint8_t length; /* length */
|
qse_uint8_t length; /* length */
|
||||||
qse_uint32_t vendor; /* in network-byte order */
|
qse_uint32_t vendor; /* in network-byte order */
|
||||||
|
|
||||||
|
/* followed by a standard attribute */
|
||||||
|
qse_rad_attr_hdr_t vs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qse_rad_extvsattr_hdr_t
|
struct qse_rad_xvsattr_hdr_t
|
||||||
{
|
{
|
||||||
qse_uint8_t id; /* one of 241-244 */
|
qse_uint8_t type; /* one of 241-244 */
|
||||||
qse_uint8_t length;
|
qse_uint8_t length;
|
||||||
qse_uint8_t xid; /* extended type. 26 for evs */
|
qse_uint8_t xtype; /* extended type. 26 for evs(extended vendor specific) attribute */
|
||||||
qse_uint32_t vendor; /* in network-byte order */
|
qse_uint32_t vendor; /* in network-byte order */
|
||||||
qse_uint8_t evsid;
|
|
||||||
|
/* followed by a standard attribute */
|
||||||
|
qse_rad_attr_hdr_t xvs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct qse_rad_lxvsattr_hdr_t
|
||||||
|
{
|
||||||
|
qse_uint8_t type; /* 245, 246*/
|
||||||
|
qse_uint8_t length;
|
||||||
|
qse_uint8_t xtype; /* extended type. 26 for evs(extended vendor specific) attribute */
|
||||||
|
qse_uint32_t vendor; /* in network-byte order */
|
||||||
|
|
||||||
|
/* followed by an extended attribute */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
qse_uint8_t type;
|
||||||
|
qse_uint8_t flags; /* bit 7: continuation, bit 6-0: reserved. */
|
||||||
|
qse_uint8_t length;
|
||||||
|
} lxvs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qse_rad_attr_uint32_t
|
struct qse_rad_attr_uint32_t
|
||||||
@ -126,7 +168,7 @@ typedef int (*qse_rad_attr_walker_t) (
|
|||||||
void* ctx
|
void* ctx
|
||||||
);
|
);
|
||||||
|
|
||||||
enum qse_rad_attr_id_t
|
enum qse_rad_attr_type_t
|
||||||
{
|
{
|
||||||
QSE_RAD_ATTR_USER_NAME = 1, /* string */
|
QSE_RAD_ATTR_USER_NAME = 1, /* string */
|
||||||
QSE_RAD_ATTR_USER_PASSWORD = 2, /* string encrypted */
|
QSE_RAD_ATTR_USER_PASSWORD = 2, /* string encrypted */
|
||||||
@ -154,9 +196,20 @@ enum qse_rad_attr_id_t
|
|||||||
QSE_RAD_ATTR_NAS_PORT_TYPE = 61, /* integer */
|
QSE_RAD_ATTR_NAS_PORT_TYPE = 61, /* integer */
|
||||||
QSE_RAD_ATTR_ACCT_INTERIM_INTERVAL = 85, /* integer */
|
QSE_RAD_ATTR_ACCT_INTERIM_INTERVAL = 85, /* integer */
|
||||||
QSE_RAD_ATTR_NAS_PORT_ID = 87, /* string */
|
QSE_RAD_ATTR_NAS_PORT_ID = 87, /* string */
|
||||||
QSE_RAD_ATTR_FRAMED_IPV6_PREFIX = 97 /* ipv6prefix */
|
QSE_RAD_ATTR_FRAMED_IPV6_PREFIX = 97, /* ipv6prefix */
|
||||||
|
|
||||||
|
QSE_RAD_ATTR_EXTENDED_1 = 241,
|
||||||
|
QSE_RAD_ATTR_EXTENDED_2 = 242,
|
||||||
|
QSE_RAD_ATTR_EXTENDED_3 = 243,
|
||||||
|
QSE_RAD_ATTR_EXTENDED_4 = 244,
|
||||||
|
QSE_RAD_ATTR_EXTENDED_5 = 245, /* long extended */
|
||||||
|
QSE_RAD_ATTR_EXTENDED_6 = 246, /* long extended */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define QSE_RAD_ATTR_IS_SHORT_EXTENDED(attrtype) ((attrtype) >= QSE_RAD_ATTR_EXTENDED_1 && (attrtype) <= QSE_RAD_ATTR_EXTENDED_4)
|
||||||
|
#define QSE_RAD_ATTR_IS_LONG_EXTENDED(attrtype) ((attrtype) >= QSE_RAD_ATTR_EXTENDED_5 && (attrtype) <= QSE_RAD_ATTR_EXTENDED_6)
|
||||||
|
#define QSE_RAD_ATTR_IS_EXTENDED(attrtype) ((attrtype) >= QSE_RAD_ATTR_EXTENDED_1 && (attrtype) <= QSE_RAD_ATTR_EXTENDED_6)
|
||||||
|
|
||||||
enum qse_rad_attr_acct_status_type_t
|
enum qse_rad_attr_acct_status_type_t
|
||||||
{
|
{
|
||||||
QSE_RAD_ATTR_ACCT_STATUS_TYPE_START = 1, /* accounting start */
|
QSE_RAD_ATTR_ACCT_STATUS_TYPE_START = 1, /* accounting start */
|
||||||
@ -213,10 +266,25 @@ QSE_EXPORT void qse_rad_initialize (
|
|||||||
|
|
||||||
QSE_EXPORT qse_rad_attr_hdr_t* qse_rad_find_attribute (
|
QSE_EXPORT qse_rad_attr_hdr_t* qse_rad_find_attribute (
|
||||||
qse_rad_hdr_t* hdr,
|
qse_rad_hdr_t* hdr,
|
||||||
qse_uint8_t attrid,
|
qse_uint8_t attrtype,
|
||||||
int index
|
int index
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT qse_rad_vsattr_hdr_t* qse_rad_find_vsattr (
|
||||||
|
qse_rad_hdr_t* hdr,
|
||||||
|
qse_uint32_t vendor,
|
||||||
|
qse_uint8_t attrtype,
|
||||||
|
int index
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT qse_rad_xvsattr_hdr_t* qse_rad_find_extended_vsattr (
|
||||||
|
qse_rad_hdr_t* hdr,
|
||||||
|
qse_uint32_t vendor,
|
||||||
|
qse_uint8_t xtype,
|
||||||
|
qse_uint8_t attrtype,
|
||||||
|
int index
|
||||||
|
);
|
||||||
|
|
||||||
QSE_EXPORT qse_rad_attr_hdr_t* qse_rad_find_vendor_specific_attribute (
|
QSE_EXPORT qse_rad_attr_hdr_t* qse_rad_find_vendor_specific_attribute (
|
||||||
qse_rad_hdr_t* hdr,
|
qse_rad_hdr_t* hdr,
|
||||||
qse_uint32_t vendor,
|
qse_uint32_t vendor,
|
||||||
@ -238,24 +306,55 @@ QSE_EXPORT int qse_rad_insert_attribute (
|
|||||||
qse_uint8_t len
|
qse_uint8_t len
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_rad_insert_extended_attribute (
|
||||||
|
qse_rad_hdr_t* auth,
|
||||||
|
int max,
|
||||||
|
qse_uint8_t xtype,
|
||||||
|
qse_uint8_t attrtype,
|
||||||
|
const void* ptr,
|
||||||
|
qse_uint8_t len,
|
||||||
|
qse_uint8_t lxflags
|
||||||
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_rad_insert_vendor_specific_attribute (
|
QSE_EXPORT int qse_rad_insert_vendor_specific_attribute (
|
||||||
qse_rad_hdr_t* auth,
|
qse_rad_hdr_t* auth,
|
||||||
int max,
|
int max,
|
||||||
qse_uint32_t vendor,
|
qse_uint32_t vendor,
|
||||||
qse_uint8_t attrid,
|
qse_uint8_t attrtype,
|
||||||
const void* ptr,
|
const void* ptr,
|
||||||
qse_uint8_t len
|
qse_uint8_t len
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_rad_insert_extended_vendor_specific_attribute (
|
||||||
|
qse_rad_hdr_t* auth,
|
||||||
|
int max,
|
||||||
|
qse_uint32_t vendor,
|
||||||
|
qse_uint8_t xtype, /* QSE_RAD_ATTR_EXTENDED_X */
|
||||||
|
qse_uint8_t attrtype,
|
||||||
|
const void* ptr,
|
||||||
|
qse_uint8_t len,
|
||||||
|
qse_uint8_t lxflags
|
||||||
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_rad_delete_attribute (
|
QSE_EXPORT int qse_rad_delete_attribute (
|
||||||
qse_rad_hdr_t* hdr,
|
qse_rad_hdr_t* auth,
|
||||||
qse_uint8_t attrid
|
qse_uint8_t attrtype,
|
||||||
|
int index
|
||||||
);
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_rad_delete_vendor_specific_attribute (
|
QSE_EXPORT int qse_rad_delete_vendor_specific_attribute (
|
||||||
qse_rad_hdr_t* hdr,
|
qse_rad_hdr_t* auth,
|
||||||
qse_uint32_t vendor,
|
qse_uint32_t vendor,
|
||||||
qse_uint8_t attrid
|
qse_uint8_t attrtype,
|
||||||
|
int index
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_rad_delete_extended_vendor_specific_attribute (
|
||||||
|
qse_rad_hdr_t* auth,
|
||||||
|
qse_uint32_t vendor,
|
||||||
|
qse_uint8_t xtype, /* QSE_RAD_ATTR_EXTENDED_X */
|
||||||
|
qse_uint8_t attrtype,
|
||||||
|
int index
|
||||||
);
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_rad_insert_string_attribute (
|
QSE_EXPORT int qse_rad_insert_string_attribute (
|
||||||
@ -318,18 +417,6 @@ QSE_EXPORT int qse_rad_insert_giga_attribute (
|
|||||||
qse_uint64_t value
|
qse_uint64_t value
|
||||||
);
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_rad_insert_extended_vendor_specific_attribute (
|
|
||||||
qse_rad_hdr_t* auth,
|
|
||||||
int max,
|
|
||||||
qse_uint8_t base, /* one of 241-244 */
|
|
||||||
qse_uint32_t vendor,
|
|
||||||
qse_uint8_t attrid,
|
|
||||||
const void* ptr,
|
|
||||||
qse_uint8_t len
|
|
||||||
);
|
|
||||||
|
|
||||||
/* TODO: QSE_EXPORT int qse_rad_delete_extended_vendor_specific_attribute () */
|
|
||||||
|
|
||||||
QSE_EXPORT int qse_rad_set_user_password (
|
QSE_EXPORT int qse_rad_set_user_password (
|
||||||
qse_rad_hdr_t* auth,
|
qse_rad_hdr_t* auth,
|
||||||
int max,
|
int max,
|
||||||
|
@ -1453,7 +1453,6 @@ static int process_attribute (
|
|||||||
flags.has_tlv = 1;
|
flags.has_tlv = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: what is tlv???
|
|
||||||
if (block_tlv)
|
if (block_tlv)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1662,7 +1661,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t* fn, const qse_char_t*
|
|||||||
const qse_char_t* b = qse_basename(src_file);
|
const qse_char_t* b = qse_basename(src_file);
|
||||||
if (b != src_file)
|
if (b != src_file)
|
||||||
{
|
{
|
||||||
fname = qse_substbasenamedup (src_file, fn, dic->mmgr);
|
fname = qse_substbasenamedup(src_file, fn, dic->mmgr);
|
||||||
if (!fname)
|
if (!fname)
|
||||||
{
|
{
|
||||||
qse_raddic_seterrfmt (dic, QSE_RADDIC_ENOMEM, QSE_T("%s[%zd]: out of memory before including %s"), fn);
|
qse_raddic_seterrfmt (dic, QSE_RADDIC_ENOMEM, QSE_T("%s[%zd]: out of memory before including %s"), fn);
|
||||||
|
@ -89,90 +89,240 @@ static void fill_authenticator_randomly (void* authenticator, int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_rad_attr_hdr_t* find_attribute (qse_rad_attr_hdr_t* attr, int* len, qse_uint8_t attrid)
|
static qse_rad_attr_hdr_t* find_attribute (qse_rad_attr_hdr_t* attr, int* len, qse_uint8_t attrtype)
|
||||||
{
|
{
|
||||||
int rem = *len;
|
int rem = *len;
|
||||||
|
|
||||||
while (rem >= QSE_SIZEOF(*attr))
|
while (rem >= QSE_SIZEOF(*attr))
|
||||||
{
|
{
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
if (rem < attr->length) return NULL;
|
if (rem < attr->length) return QSE_NULL;
|
||||||
if (attr->length < QSE_SIZEOF(*attr))
|
if (attr->length < QSE_SIZEOF(*attr))
|
||||||
{
|
{
|
||||||
/* attribute length cannot be less than the header size.
|
/* attribute length cannot be less than the header size.
|
||||||
* the packet could be corrupted... */
|
* the packet could be corrupted... */
|
||||||
return NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rem -= attr->length;
|
rem -= attr->length;
|
||||||
if (attr->id == attrid)
|
if (attr->type == attrtype)
|
||||||
{
|
{
|
||||||
*len = rem;
|
*len = rem; /* remaining length */
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = (qse_rad_attr_hdr_t*) ((char*) attr + attr->length);
|
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_rad_attr_hdr_t* qse_rad_find_attribute (qse_rad_hdr_t* hdr, qse_uint8_t attrid, int index)
|
static qse_rad_attr_hdr_t* find_extended_attribute (qse_rad_attr_hdr_t* attr, int* len, qse_uint8_t xtype, qse_uint8_t attrtype)
|
||||||
{
|
{
|
||||||
qse_rad_attr_hdr_t *attr = (qse_rad_attr_hdr_t*)(hdr+1);
|
int rem = *len;
|
||||||
int len = qse_ntoh16(hdr->length) - QSE_SIZEOF(*hdr);
|
|
||||||
attr = find_attribute (attr, &len, attrid);
|
/* xtype must be one of the followings:
|
||||||
while (attr)
|
* QSE_RAD_ATTR_EXTENDED_1
|
||||||
|
* QSE_RAD_ATTR_EXTENDED_2
|
||||||
|
* QSE_RAD_ATTR_EXTENDED_3
|
||||||
|
* QSE_RAD_ATTR_EXTENDED_4
|
||||||
|
* QSE_RAD_ATTR_EXTENDED_5
|
||||||
|
* QSE_RAD_ATTR_EXTENDED_6
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (rem >= QSE_SIZEOF(*attr))
|
||||||
{
|
{
|
||||||
if (index <= 0) return attr;
|
/* sanity checks */
|
||||||
index--;
|
if (rem < attr->length) return QSE_NULL;
|
||||||
attr = find_attribute ((qse_rad_attr_hdr_t*)((char*)attr+attr->length), &len, attrid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
/* attribute length cannot be less than the header size.
|
||||||
}
|
* the packet could be corrupted... */
|
||||||
|
if (attr->length < QSE_SIZEOF(*attr)) goto oops;
|
||||||
|
|
||||||
qse_rad_attr_hdr_t* qse_rad_find_vendor_specific_attribute (qse_rad_hdr_t* hdr, qse_uint32_t vendor, qse_uint8_t attrid, int index)
|
rem -= attr->length;
|
||||||
{
|
if (attr->type == xtype)
|
||||||
qse_rad_attr_hdr_t *attr = (qse_rad_attr_hdr_t*)(hdr+1);
|
|
||||||
int len = qse_ntoh16(hdr->length) - QSE_SIZEOF(*hdr);
|
|
||||||
|
|
||||||
attr = find_attribute (attr, &len, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
|
||||||
while (attr)
|
|
||||||
{
|
|
||||||
qse_rad_vsattr_hdr_t* vsattr;
|
|
||||||
|
|
||||||
if (attr->length >= QSE_SIZEOF(*vsattr)) /* sanity check */
|
|
||||||
{
|
{
|
||||||
vsattr = (qse_rad_vsattr_hdr_t*)attr;
|
qse_uint8_t xattrtype;
|
||||||
|
|
||||||
if (qse_ntoh32(vsattr->vendor) == vendor)
|
if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||||
{
|
{
|
||||||
qse_rad_attr_hdr_t* subattr;
|
qse_rad_lxattr_hdr_t* lxattr;
|
||||||
int sublen = vsattr->length - QSE_SIZEOF(*vsattr);
|
lxattr = (qse_rad_lxattr_hdr_t*)attr;
|
||||||
|
if (lxattr->length < QSE_SIZEOF(*lxattr)) goto oops;
|
||||||
|
xattrtype = lxattr->xtype;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qse_rad_xattr_hdr_t* xattr;
|
||||||
|
xattr = (qse_rad_xattr_hdr_t*)attr;
|
||||||
|
if (xattr->length < QSE_SIZEOF(*xattr)) goto oops;
|
||||||
|
xattrtype = xattr->xtype;
|
||||||
|
}
|
||||||
|
|
||||||
if (sublen >= QSE_SIZEOF(*subattr)) /* sanity check */
|
if (xattrtype == attrtype)
|
||||||
|
{
|
||||||
|
*len = rem;
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
oops:
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_rad_attr_hdr_t* qse_rad_find_attribute (qse_rad_hdr_t* hdr, qse_uint8_t attrtype, int index)
|
||||||
|
{
|
||||||
|
qse_rad_attr_hdr_t *attr = (qse_rad_attr_hdr_t*)(hdr+1);
|
||||||
|
|
||||||
|
if (qse_ntoh16(hdr->length) >= QSE_SIZEOF(*hdr))
|
||||||
|
{
|
||||||
|
int len = qse_ntoh16(hdr->length) - QSE_SIZEOF(*hdr);
|
||||||
|
attr = find_attribute(attr, &len, attrtype);
|
||||||
|
while (attr)
|
||||||
|
{
|
||||||
|
if (index <= 0) return attr;
|
||||||
|
index--;
|
||||||
|
attr = find_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr+attr->length), &len, attrtype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_rad_attr_hdr_t* qse_rad_find_extended_attribute (qse_rad_hdr_t* hdr, qse_uint8_t xtype, qse_uint8_t attrtype, int index)
|
||||||
|
{
|
||||||
|
qse_rad_attr_hdr_t *attr = (qse_rad_attr_hdr_t*)(hdr + 1);
|
||||||
|
|
||||||
|
if (QSE_RAD_ATTR_IS_EXTENDED(xtype) && qse_ntoh16(hdr->length) >= QSE_SIZEOF(*hdr))
|
||||||
|
{
|
||||||
|
int len = qse_ntoh16(hdr->length) - QSE_SIZEOF(*hdr);
|
||||||
|
attr = find_extended_attribute(attr, &len, xtype, attrtype);
|
||||||
|
while (attr)
|
||||||
|
{
|
||||||
|
if (index <= 0) return attr;
|
||||||
|
index--;
|
||||||
|
attr = find_extended_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length), &len, xtype, attrtype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_rad_vsattr_hdr_t* qse_rad_find_vsattr (qse_rad_hdr_t* hdr, qse_uint32_t vendor, qse_uint8_t attrtype, int index)
|
||||||
|
{
|
||||||
|
qse_rad_attr_hdr_t *attr = (qse_rad_attr_hdr_t*)(hdr+1);
|
||||||
|
|
||||||
|
if (qse_ntoh16(hdr->length) >= QSE_SIZEOF(*hdr))
|
||||||
|
{
|
||||||
|
int len = qse_ntoh16(hdr->length) - QSE_SIZEOF(*hdr);
|
||||||
|
|
||||||
|
attr = find_attribute(attr, &len, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||||
|
while (attr)
|
||||||
|
{
|
||||||
|
qse_rad_vsattr_hdr_t* vsattr;
|
||||||
|
|
||||||
|
if (attr->length >= QSE_SIZEOF(*vsattr)) /* sanity check */
|
||||||
|
{
|
||||||
|
vsattr = (qse_rad_vsattr_hdr_t*)attr;
|
||||||
|
|
||||||
|
if (qse_ntoh32(vsattr->vendor) == vendor && vsattr->vs.type == attrtype)
|
||||||
{
|
{
|
||||||
subattr = (qse_rad_attr_hdr_t*)(vsattr + 1);
|
int val_len;
|
||||||
if (subattr->id == attrid && subattr->length == sublen)
|
|
||||||
|
val_len = (int)vsattr->length - QSE_SIZEOF(*vsattr);
|
||||||
|
|
||||||
|
if ((int)vsattr->vs.length == val_len + QSE_SIZEOF(vsattr->vs))
|
||||||
{
|
{
|
||||||
if (index <= 0) return subattr;
|
if (index <= 0) return vsattr;
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
attr = find_attribute ((qse_rad_attr_hdr_t*)((char*)attr+attr->length), &len, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
attr = find_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length), &len, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_rad_xvsattr_hdr_t* qse_rad_find_extended_vsattr (qse_rad_hdr_t* hdr, qse_uint32_t vendor, qse_uint8_t xtype, qse_uint8_t attrtype, int index)
|
||||||
|
{
|
||||||
|
qse_rad_attr_hdr_t *attr = (qse_rad_attr_hdr_t*)(hdr+1);
|
||||||
|
|
||||||
|
if (QSE_RAD_ATTR_IS_EXTENDED(xtype) && qse_ntoh16(hdr->length) >= QSE_SIZEOF(*hdr))
|
||||||
|
{
|
||||||
|
int len = qse_ntoh16(hdr->length) - QSE_SIZEOF(*hdr);
|
||||||
|
|
||||||
|
attr = find_extended_attribute(attr, &len, xtype, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||||
|
while (attr)
|
||||||
|
{
|
||||||
|
if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
qse_rad_lxvsattr_hdr_t* lxvsattr;
|
||||||
|
if (attr->length >= QSE_SIZEOF(*lxvsattr)) /* sanity check */
|
||||||
|
{
|
||||||
|
lxvsattr = (qse_rad_lxvsattr_hdr_t*)attr;
|
||||||
|
|
||||||
|
if (qse_ntoh32(lxvsattr->vendor) == vendor && lxvsattr->lxvs.type == attrtype)
|
||||||
|
{
|
||||||
|
int val_len;
|
||||||
|
|
||||||
|
val_len = (int)lxvsattr->length - QSE_SIZEOF(*lxvsattr);
|
||||||
|
|
||||||
|
if ((int)lxvsattr->lxvs.length == val_len + QSE_SIZEOF(lxvsattr->lxvs))
|
||||||
|
{
|
||||||
|
/* the caller must check if the extended type is long.
|
||||||
|
* if long, it must cast back to qse_rad_lxvsattr_hdr_t* */
|
||||||
|
if (index <= 0) return (qse_rad_xvsattr_hdr_t*)lxvsattr;
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qse_rad_xvsattr_hdr_t* xvsattr;
|
||||||
|
if (attr->length >= QSE_SIZEOF(*xvsattr)) /* sanity check */
|
||||||
|
{
|
||||||
|
xvsattr = (qse_rad_xvsattr_hdr_t*)attr;
|
||||||
|
|
||||||
|
if (qse_ntoh32(xvsattr->vendor) == vendor && xvsattr->xvs.type == attrtype)
|
||||||
|
{
|
||||||
|
int val_len;
|
||||||
|
|
||||||
|
val_len = (int)xvsattr->length - QSE_SIZEOF(*xvsattr);
|
||||||
|
|
||||||
|
if ((int)xvsattr->xvs.length == val_len + QSE_SIZEOF(xvsattr->xvs))
|
||||||
|
{
|
||||||
|
if (index <= 0) return xvsattr;
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = find_extended_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length), &len, xtype, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_rad_attr_hdr_t* qse_rad_find_vendor_specific_attribute (qse_rad_hdr_t* hdr, qse_uint32_t vendor, qse_uint8_t attrtype, int index)
|
||||||
|
{
|
||||||
|
qse_rad_vsattr_hdr_t* vsattr;
|
||||||
|
vsattr = qse_rad_find_vsattr(hdr, vendor, attrtype, index);
|
||||||
|
return vsattr? &vsattr->vs: QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_walk_attributes (const qse_rad_hdr_t* hdr, qse_rad_attr_walker_t walker, void* ctx)
|
int qse_rad_walk_attributes (const qse_rad_hdr_t* hdr, qse_rad_attr_walker_t walker, void* ctx)
|
||||||
{
|
{
|
||||||
int totlen, rem;
|
int totlen, rem;
|
||||||
qse_rad_attr_hdr_t *attr;
|
qse_rad_attr_hdr_t* attr;
|
||||||
|
|
||||||
totlen = qse_ntoh16(hdr->length);
|
totlen = qse_ntoh16(hdr->length);
|
||||||
if (totlen < QSE_SIZEOF(*hdr)) return -1;
|
if (totlen < QSE_SIZEOF(*hdr)) return -1;
|
||||||
@ -192,33 +342,30 @@ int qse_rad_walk_attributes (const qse_rad_hdr_t* hdr, qse_rad_attr_walker_t wal
|
|||||||
|
|
||||||
rem -= attr->length;
|
rem -= attr->length;
|
||||||
|
|
||||||
if (attr->id == QSE_RAD_ATTR_VENDOR_SPECIFIC)
|
if (attr->type == QSE_RAD_ATTR_VENDOR_SPECIFIC)
|
||||||
{
|
{
|
||||||
qse_rad_vsattr_hdr_t* vsattr;
|
qse_rad_vsattr_hdr_t* vsattr;
|
||||||
qse_rad_attr_hdr_t* subattr;
|
int val_len;
|
||||||
int sublen;
|
|
||||||
|
|
||||||
if (attr->length < QSE_SIZEOF(*vsattr)) return -1;
|
if (attr->length < QSE_SIZEOF(*vsattr)) return -1;
|
||||||
vsattr = (qse_rad_vsattr_hdr_t*)attr;
|
vsattr = (qse_rad_vsattr_hdr_t*)attr;
|
||||||
|
|
||||||
sublen = vsattr->length - QSE_SIZEOF(*vsattr);
|
val_len = (int)vsattr->length - QSE_SIZEOF(*vsattr);
|
||||||
if (sublen < QSE_SIZEOF(*subattr)) return -1;
|
if ((int)vsattr->vs.length != val_len + QSE_SIZEOF(vsattr->vs)) return -1;
|
||||||
subattr = (qse_rad_attr_hdr_t*)(vsattr + 1);
|
|
||||||
if (subattr->length != sublen) return -1;
|
|
||||||
|
|
||||||
/* if this vendor happens to be 0, walker can't tell
|
/* if this vendor happens to be 0, walker can't tell
|
||||||
* if it is vendor specific or not because 0 is passed in
|
* if it is vendor specific or not because 0 is passed in
|
||||||
* for non-VSAs. but i don't care. in reality,
|
* for non-VSAs. but i don't care. in reality,
|
||||||
* 0 is reserved in IANA enterpirse number assignments.
|
* 0 is reserved in IANA enterpirse number assignments.
|
||||||
* (http://www.iana.org/assignments/enterprise-numbers) */
|
* (http://www.iana.org/assignments/enterprise-numbers) */
|
||||||
if (walker (hdr, qse_ntoh32(vsattr->vendor), subattr, ctx) <= -1) return -1;
|
if (walker(hdr, qse_ntoh32(vsattr->vendor), &vsattr->vs, ctx) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (walker (hdr, 0, attr, ctx) <= -1) return -1;
|
if (walker(hdr, 0, attr, ctx) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = (qse_rad_attr_hdr_t*) ((char*) attr + attr->length);
|
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*) attr + attr->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -239,8 +386,8 @@ int qse_rad_insert_attribute (
|
|||||||
|
|
||||||
if (new_auth_len > max) return -1;
|
if (new_auth_len > max) return -1;
|
||||||
|
|
||||||
attr = (qse_rad_attr_hdr_t*) ((char*)auth + auth_len);
|
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*)auth + auth_len);
|
||||||
attr->id = id;
|
attr->type = id;
|
||||||
attr->length = new_auth_len - auth_len;
|
attr->length = new_auth_len - auth_len;
|
||||||
QSE_MEMCPY (attr + 1, ptr, len);
|
QSE_MEMCPY (attr + 1, ptr, len);
|
||||||
auth->length = qse_hton16(new_auth_len);
|
auth->length = qse_hton16(new_auth_len);
|
||||||
@ -248,36 +395,135 @@ int qse_rad_insert_attribute (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_insert_vendor_specific_attribute (
|
int qse_rad_insert_extended_attribute (
|
||||||
qse_rad_hdr_t* auth, int max,
|
qse_rad_hdr_t* auth, int max, qse_uint8_t xtype,
|
||||||
qse_uint32_t vendor, qse_uint8_t attrid, const void* ptr, qse_uint8_t len)
|
qse_uint8_t attrtype, const void* ptr, qse_uint8_t len, qse_uint8_t lxflags)
|
||||||
{
|
{
|
||||||
qse_rad_vsattr_hdr_t* attr;
|
qse_rad_xattr_hdr_t* xattr;
|
||||||
qse_rad_attr_hdr_t* subattr;
|
|
||||||
int auth_len = qse_ntoh16(auth->length);
|
int auth_len = qse_ntoh16(auth->length);
|
||||||
int new_auth_len;
|
int new_auth_len, maxvallen, hdrlen;
|
||||||
|
|
||||||
|
if (QSE_RAD_ATTR_IS_SHORT_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
maxvallen = QSE_RAD_MAX_XATTR_VALUE_LEN;
|
||||||
|
hdrlen = QSE_SIZEOF(qse_rad_xattr_hdr_t);
|
||||||
|
}
|
||||||
|
else if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
maxvallen = QSE_RAD_MAX_LXATTR_VALUE_LEN;
|
||||||
|
hdrlen = QSE_SIZEOF(qse_rad_lxattr_hdr_t);
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
|
||||||
/*if (len > QSE_RAD_MAX_VSATTR_VALUE_LEN) return -1;*/
|
/*if (len > maxvallen) return -1;*/
|
||||||
if (len > QSE_RAD_MAX_VSATTR_VALUE_LEN) len = QSE_RAD_MAX_VSATTR_VALUE_LEN;
|
if (len > maxvallen) len = maxvallen;
|
||||||
new_auth_len = auth_len + len + QSE_SIZEOF(*attr) + QSE_SIZEOF(*subattr);
|
new_auth_len = auth_len + hdrlen + len;
|
||||||
|
|
||||||
if (new_auth_len > max) return -1;
|
if (new_auth_len > max) return -1;
|
||||||
|
|
||||||
attr = (qse_rad_vsattr_hdr_t*) ((char*)auth + auth_len);
|
xattr = (qse_rad_xattr_hdr_t*)((qse_uint8_t*)auth + auth_len);
|
||||||
attr->id = QSE_RAD_ATTR_VENDOR_SPECIFIC;
|
xattr->type = xtype;
|
||||||
attr->length = new_auth_len - auth_len;
|
xattr->length = new_auth_len - auth_len;
|
||||||
attr->vendor = qse_hton32 (vendor);
|
if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
qse_rad_lxattr_hdr_t* lxattr;
|
||||||
|
lxattr = (qse_rad_lxattr_hdr_t*)xattr;
|
||||||
|
lxattr->xtype = attrtype;
|
||||||
|
lxattr->xflags = lxflags;
|
||||||
|
QSE_MEMCPY (lxattr + 1, ptr, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xattr->xtype = attrtype;
|
||||||
|
QSE_MEMCPY (xattr + 1, ptr, len);
|
||||||
|
}
|
||||||
|
auth->length = qse_hton16(new_auth_len);
|
||||||
|
|
||||||
subattr = (qse_rad_attr_hdr_t*)(attr + 1);
|
return 0;
|
||||||
subattr->id = attrid;
|
}
|
||||||
subattr->length = len + QSE_SIZEOF(*subattr);
|
|
||||||
QSE_MEMCPY (subattr + 1, ptr, len);
|
int qse_rad_insert_vendor_specific_attribute (
|
||||||
|
qse_rad_hdr_t* auth, int max,
|
||||||
|
qse_uint32_t vendor, qse_uint8_t attrtype, const void* ptr, qse_uint8_t len)
|
||||||
|
{
|
||||||
|
qse_rad_vsattr_hdr_t* vsattr;
|
||||||
|
int auth_len = qse_ntoh16(auth->length);
|
||||||
|
int new_auth_len;
|
||||||
|
|
||||||
|
/*if (len > QSE_RAD_MAX_VSATTR_VALUE_LEN) return -1;*/
|
||||||
|
if (len > QSE_RAD_MAX_VSATTR_VALUE_LEN) len = QSE_RAD_MAX_VSATTR_VALUE_LEN;
|
||||||
|
new_auth_len = auth_len + QSE_SIZEOF(*vsattr) + len;
|
||||||
|
|
||||||
|
if (new_auth_len > max) return -1;
|
||||||
|
|
||||||
|
vsattr = (qse_rad_vsattr_hdr_t*)((qse_uint8_t*)auth + auth_len);
|
||||||
|
vsattr->type = QSE_RAD_ATTR_VENDOR_SPECIFIC;
|
||||||
|
vsattr->length = new_auth_len - auth_len;
|
||||||
|
vsattr->vendor = qse_hton32(vendor);
|
||||||
|
|
||||||
|
vsattr->vs.type = attrtype;
|
||||||
|
vsattr->vs.length = QSE_SIZEOF(vsattr->vs) + len;
|
||||||
|
QSE_MEMCPY (vsattr + 1, ptr, len);
|
||||||
|
|
||||||
auth->length = qse_hton16(new_auth_len);
|
auth->length = qse_hton16(new_auth_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qse_rad_insert_extended_vendor_specific_attribute (
|
||||||
|
qse_rad_hdr_t* auth, int max, qse_uint32_t vendor, qse_uint8_t xtype,
|
||||||
|
qse_uint8_t attrtype, const void* ptr, qse_uint8_t len, qse_uint8_t lxflags)
|
||||||
|
{
|
||||||
|
/* RFC6929 */
|
||||||
|
qse_rad_xvsattr_hdr_t* xvsattr;
|
||||||
|
int auth_len = qse_ntoh16(auth->length);
|
||||||
|
int new_auth_len, maxvallen, hdrlen;
|
||||||
|
|
||||||
|
if (QSE_RAD_ATTR_IS_SHORT_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
maxvallen = QSE_RAD_MAX_XVSATTR_VALUE_LEN;
|
||||||
|
hdrlen = QSE_SIZEOF(qse_rad_xvsattr_hdr_t);
|
||||||
|
}
|
||||||
|
else if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
maxvallen = QSE_RAD_MAX_LXVSATTR_VALUE_LEN;
|
||||||
|
hdrlen = QSE_SIZEOF(qse_rad_lxvsattr_hdr_t);
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
|
||||||
|
/*if (len > maxvallen) return -1;*/
|
||||||
|
if (len > maxvallen) len = QSE_RAD_MAX_XVSATTR_VALUE_LEN;
|
||||||
|
new_auth_len = auth_len + hdrlen + len;
|
||||||
|
|
||||||
|
if (new_auth_len > max) return -1;
|
||||||
|
|
||||||
|
xvsattr = (qse_rad_xvsattr_hdr_t*)((qse_uint8_t*)auth + auth_len);
|
||||||
|
xvsattr->type = xtype;
|
||||||
|
xvsattr->length = new_auth_len - auth_len;
|
||||||
|
xvsattr->xtype = QSE_RAD_ATTR_VENDOR_SPECIFIC;
|
||||||
|
xvsattr->vendor = qse_hton32(vendor);
|
||||||
|
|
||||||
|
if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||||
|
{
|
||||||
|
/* this function is still low-level. it doesn't handle continuation of big data */
|
||||||
|
qse_rad_lxvsattr_hdr_t* lxvsattr;
|
||||||
|
lxvsattr = (qse_rad_lxvsattr_hdr_t*)xvsattr;
|
||||||
|
lxvsattr->lxvs.type = attrtype;
|
||||||
|
lxvsattr->lxvs.flags = lxflags;
|
||||||
|
lxvsattr->lxvs.length = len + QSE_SIZEOF(lxvsattr->lxvs);
|
||||||
|
QSE_MEMCPY (lxvsattr + 1, ptr, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xvsattr->xvs.type = attrtype;
|
||||||
|
xvsattr->xvs.length = len + QSE_SIZEOF(xvsattr->xvs);
|
||||||
|
QSE_MEMCPY (xvsattr + 1, ptr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
auth->length = qse_hton16(new_auth_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int delete_attribute (qse_rad_hdr_t* auth, qse_rad_attr_hdr_t* attr)
|
static int delete_attribute (qse_rad_hdr_t* auth, qse_rad_attr_hdr_t* attr)
|
||||||
{
|
{
|
||||||
qse_uint16_t auth_len;
|
qse_uint16_t auth_len;
|
||||||
@ -294,26 +540,34 @@ static int delete_attribute (qse_rad_hdr_t* auth, qse_rad_attr_hdr_t* attr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_delete_attribute (qse_rad_hdr_t* auth, qse_uint8_t attrid)
|
int qse_rad_delete_attribute (qse_rad_hdr_t* auth, qse_uint8_t attrtype, int index)
|
||||||
{
|
{
|
||||||
qse_rad_attr_hdr_t* attr;
|
qse_rad_attr_hdr_t* attr;
|
||||||
|
|
||||||
attr = qse_rad_find_attribute (auth, attrid, 0);
|
attr = qse_rad_find_attribute(auth, attrtype, index);
|
||||||
if (attr == NULL) return 0; /* not found */
|
if (!attr) return 0; /* not found */
|
||||||
return (delete_attribute (auth, attr) <= -1)? -1: 1;
|
return (delete_attribute(auth, attr) <= -1)? -1: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_delete_vendor_specific_attribute (
|
int qse_rad_delete_vendor_specific_attribute (
|
||||||
qse_rad_hdr_t* auth, qse_uint32_t vendor, qse_uint8_t attrid)
|
qse_rad_hdr_t* auth, qse_uint32_t vendor, qse_uint8_t attrtype, int index)
|
||||||
{
|
{
|
||||||
qse_rad_attr_hdr_t* attr;
|
|
||||||
qse_rad_vsattr_hdr_t* vsattr;
|
qse_rad_vsattr_hdr_t* vsattr;
|
||||||
|
|
||||||
attr = qse_rad_find_vendor_specific_attribute (auth, vendor, attrid, 0);
|
vsattr = qse_rad_find_vsattr(auth, vendor, attrtype, 0);
|
||||||
if (attr == NULL) return 0; /* not found */
|
if (!vsattr) return 0; /* not found */
|
||||||
|
return (delete_attribute(auth, (qse_rad_attr_hdr_t*)vsattr) <= -1)? -1: 1;
|
||||||
|
}
|
||||||
|
|
||||||
vsattr = (qse_rad_vsattr_hdr_t*)((qse_uint8_t*)attr - QSE_SIZEOF(qse_rad_vsattr_hdr_t));
|
int qse_rad_delete_extended_vendor_specific_attribute (
|
||||||
return (delete_attribute (auth, (qse_rad_attr_hdr_t*)vsattr) <= -1)? -1: 1;
|
qse_rad_hdr_t* auth, qse_uint32_t vendor, qse_uint8_t xtype, qse_uint8_t attrtype, int index)
|
||||||
|
{
|
||||||
|
qse_rad_xvsattr_hdr_t* xvsattr;
|
||||||
|
|
||||||
|
xvsattr = qse_rad_find_extended_vsattr(auth, vendor, xtype, attrtype, 0);
|
||||||
|
if (!xvsattr) return 0; /* not found */
|
||||||
|
|
||||||
|
return (delete_attribute(auth, (qse_rad_attr_hdr_t*)xvsattr) <= -1)? -1: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_insert_string_attribute (
|
int qse_rad_insert_string_attribute (
|
||||||
@ -321,8 +575,8 @@ int qse_rad_insert_string_attribute (
|
|||||||
qse_uint8_t id, const qse_mchar_t* value)
|
qse_uint8_t id, const qse_mchar_t* value)
|
||||||
{
|
{
|
||||||
return (vendor == 0)?
|
return (vendor == 0)?
|
||||||
qse_rad_insert_attribute (auth, max, id, value, qse_mbslen(value)):
|
qse_rad_insert_attribute(auth, max, id, value, qse_mbslen(value)):
|
||||||
qse_rad_insert_vendor_specific_attribute (auth, max, vendor, id, value, qse_mbslen(value));
|
qse_rad_insert_vendor_specific_attribute(auth, max, vendor, id, value, qse_mbslen(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_insert_wide_string_attribute (
|
int qse_rad_insert_wide_string_attribute (
|
||||||
@ -333,10 +587,10 @@ int qse_rad_insert_wide_string_attribute (
|
|||||||
qse_mchar_t* val;
|
qse_mchar_t* val;
|
||||||
qse_size_t mbslen;
|
qse_size_t mbslen;
|
||||||
|
|
||||||
val = qse_wcstombsdup (value, &mbslen, QSE_MMGR_GETDFL());
|
val = qse_wcstombsdup(value, &mbslen, QSE_MMGR_GETDFL());
|
||||||
n = (vendor == 0)?
|
n = (vendor == 0)?
|
||||||
qse_rad_insert_attribute (auth, max, id, val, mbslen):
|
qse_rad_insert_attribute(auth, max, id, val, mbslen):
|
||||||
qse_rad_insert_vendor_specific_attribute (auth, max, vendor, id, val, mbslen);
|
qse_rad_insert_vendor_specific_attribute(auth, max, vendor, id, val, mbslen);
|
||||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), val);
|
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), val);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
@ -347,8 +601,8 @@ int qse_rad_insert_string_attribute_with_length (
|
|||||||
qse_uint8_t id, const qse_mchar_t* value, qse_uint8_t length)
|
qse_uint8_t id, const qse_mchar_t* value, qse_uint8_t length)
|
||||||
{
|
{
|
||||||
return (vendor == 0)?
|
return (vendor == 0)?
|
||||||
qse_rad_insert_attribute (auth, max, id, value, length):
|
qse_rad_insert_attribute(auth, max, id, value, length):
|
||||||
qse_rad_insert_vendor_specific_attribute (auth, max, vendor, id, value, length);
|
qse_rad_insert_vendor_specific_attribute(auth, max, vendor, id, value, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_insert_wide_string_attribute_with_length (
|
int qse_rad_insert_wide_string_attribute_with_length (
|
||||||
@ -359,10 +613,10 @@ int qse_rad_insert_wide_string_attribute_with_length (
|
|||||||
qse_mchar_t* val;
|
qse_mchar_t* val;
|
||||||
qse_size_t mbslen;
|
qse_size_t mbslen;
|
||||||
|
|
||||||
val = qse_wcsntombsdup (value, length, &mbslen, QSE_MMGR_GETDFL());
|
val = qse_wcsntombsdup(value, length, &mbslen, QSE_MMGR_GETDFL());
|
||||||
n = (vendor == 0)?
|
n = (vendor == 0)?
|
||||||
qse_rad_insert_attribute (auth, max, id, val, mbslen):
|
qse_rad_insert_attribute(auth, max, id, val, mbslen):
|
||||||
qse_rad_insert_vendor_specific_attribute (auth, max, vendor, id, val, mbslen);
|
qse_rad_insert_vendor_specific_attribute(auth, max, vendor, id, val, mbslen);
|
||||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), val);
|
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), val);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
@ -373,8 +627,8 @@ int qse_rad_insert_uint32_attribute (
|
|||||||
{
|
{
|
||||||
qse_uint32_t val = qse_hton32(value);
|
qse_uint32_t val = qse_hton32(value);
|
||||||
return (vendor == 0)?
|
return (vendor == 0)?
|
||||||
qse_rad_insert_attribute (auth, max, id, &val, QSE_SIZEOF(val)):
|
qse_rad_insert_attribute(auth, max, id, &val, QSE_SIZEOF(val)):
|
||||||
qse_rad_insert_vendor_specific_attribute (auth, max, vendor, id, &val, QSE_SIZEOF(val));
|
qse_rad_insert_vendor_specific_attribute(auth, max, vendor, id, &val, QSE_SIZEOF(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_insert_ipv6prefix_attribute (
|
int qse_rad_insert_ipv6prefix_attribute (
|
||||||
@ -419,8 +673,8 @@ int qse_rad_insert_ipv6prefix_attribute (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (vendor == 0)?
|
return (vendor == 0)?
|
||||||
qse_rad_insert_attribute (auth, max, id, &ipv6prefix, j + 2):
|
qse_rad_insert_attribute(auth, max, id, &ipv6prefix, j + 2):
|
||||||
qse_rad_insert_vendor_specific_attribute (auth, max, vendor, id, &ipv6prefix, j + 2);
|
qse_rad_insert_vendor_specific_attribute(auth, max, vendor, id, &ipv6prefix, j + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_rad_insert_giga_attribute (
|
int qse_rad_insert_giga_attribute (
|
||||||
@ -432,67 +686,32 @@ int qse_rad_insert_giga_attribute (
|
|||||||
|
|
||||||
if (vendor == 0)
|
if (vendor == 0)
|
||||||
{
|
{
|
||||||
if (qse_rad_insert_attribute (auth, max, low_id, &low, QSE_SIZEOF(low)) <= -1) return -1;
|
if (qse_rad_insert_attribute(auth, max, low_id, &low, QSE_SIZEOF(low)) <= -1) return -1;
|
||||||
|
|
||||||
if (value > QSE_TYPE_MAX(qse_uint32_t))
|
if (value > QSE_TYPE_MAX(qse_uint32_t))
|
||||||
{
|
{
|
||||||
qse_uint32_t high;
|
qse_uint32_t high;
|
||||||
high = value >> (QSE_SIZEOF(qse_uint32_t) * 8);
|
high = value >> (QSE_SIZEOF(qse_uint32_t) * 8);
|
||||||
high = qse_hton32(high);
|
high = qse_hton32(high);
|
||||||
if (qse_rad_insert_attribute (auth, max, high_id, &high, QSE_SIZEOF(high)) <= -1) return -1;
|
if (qse_rad_insert_attribute(auth, max, high_id, &high, QSE_SIZEOF(high)) <= -1) return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (qse_rad_insert_vendor_specific_attribute (auth, max, vendor, low_id, &low, QSE_SIZEOF(low)) <= -1) return -1;
|
if (qse_rad_insert_vendor_specific_attribute(auth, max, vendor, low_id, &low, QSE_SIZEOF(low)) <= -1) return -1;
|
||||||
|
|
||||||
if (value > QSE_TYPE_MAX(qse_uint32_t))
|
if (value > QSE_TYPE_MAX(qse_uint32_t))
|
||||||
{
|
{
|
||||||
qse_uint32_t high;
|
qse_uint32_t high;
|
||||||
high = value >> (QSE_SIZEOF(qse_uint32_t) * 8);
|
high = value >> (QSE_SIZEOF(qse_uint32_t) * 8);
|
||||||
high = qse_hton32(high);
|
high = qse_hton32(high);
|
||||||
if (qse_rad_insert_vendor_specific_attribute (auth, max, vendor, high_id, &high, QSE_SIZEOF(high)) <= -1) return -1;
|
if (qse_rad_insert_vendor_specific_attribute(auth, max, vendor, high_id, &high, QSE_SIZEOF(high)) <= -1) return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int qse_rad_insert_extended_vendor_specific_attribute (
|
|
||||||
qse_rad_hdr_t* auth, int max, qse_uint8_t base, qse_uint32_t vendor,
|
|
||||||
qse_uint8_t attrid, const void* ptr, qse_uint8_t len)
|
|
||||||
{
|
|
||||||
/* RFC6929 */
|
|
||||||
qse_rad_extvsattr_hdr_t* attr;
|
|
||||||
int auth_len = qse_ntoh16(auth->length);
|
|
||||||
int new_auth_len;
|
|
||||||
|
|
||||||
if (base < 241 && base > 244) return -1;
|
|
||||||
/* TODO: for 245 and 246, switch to long-extended format */
|
|
||||||
|
|
||||||
/*if (len > QSE_RAD_MAX_EXTVSATTR_VALUE_LEN) return -1;*/
|
|
||||||
if (len > QSE_RAD_MAX_EXTVSATTR_VALUE_LEN) len = QSE_RAD_MAX_EXTVSATTR_VALUE_LEN;
|
|
||||||
new_auth_len = auth_len + len + QSE_SIZEOF(*attr);
|
|
||||||
|
|
||||||
if (new_auth_len > max) return -1;
|
|
||||||
|
|
||||||
attr = (qse_rad_extvsattr_hdr_t*) ((char*)auth + auth_len);
|
|
||||||
attr->id = base;
|
|
||||||
attr->length = new_auth_len - auth_len;
|
|
||||||
attr->xid = QSE_RAD_ATTR_VENDOR_SPECIFIC;
|
|
||||||
attr->vendor = qse_hton32(vendor);
|
|
||||||
attr->evsid = attrid;
|
|
||||||
|
|
||||||
/* no special header for the evs-value */
|
|
||||||
QSE_MEMCPY (attr + 1, ptr, len);
|
|
||||||
|
|
||||||
auth->length = qse_hton16(new_auth_len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define PASS_BLKSIZE QSE_RAD_MAX_AUTHENTICATOR_LEN
|
#define PASS_BLKSIZE QSE_RAD_MAX_AUTHENTICATOR_LEN
|
||||||
#define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor))
|
#define ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor))
|
||||||
|
|
||||||
@ -550,8 +769,14 @@ int qse_rad_set_user_password (qse_rad_hdr_t* auth, int max, const qse_mchar_t*
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ok if not found or deleted. but not ok if an error occurred */
|
/* ok if not found or deleted. but not ok if an error occurred */
|
||||||
if (qse_rad_delete_attribute (auth, QSE_RAD_ATTR_USER_PASSWORD) <= -1) goto oops;
|
while (1)
|
||||||
if (qse_rad_insert_attribute (auth, max, QSE_RAD_ATTR_USER_PASSWORD, hashed, padlen) <= -1) goto oops;
|
{
|
||||||
|
int n;
|
||||||
|
n = qse_rad_delete_attribute(auth, QSE_RAD_ATTR_USER_PASSWORD, 0);
|
||||||
|
if (n <= -1) goto oops;
|
||||||
|
if (n == 0) break;
|
||||||
|
}
|
||||||
|
if (qse_rad_insert_attribute(auth, max, QSE_RAD_ATTR_USER_PASSWORD, hashed, padlen) <= -1) goto oops;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user