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_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_EXTVSATTR_VALUE_LEN (QSE_TYPE_MAX(qse_uint8_t) - QSE_SIZEOF(qse_rad_extvsattr_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_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_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_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;
|
||||
#if (QSE_SIZEOF_UINT64_T > 0)
|
||||
@ -82,24 +87,61 @@ struct qse_rad_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;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
qse_uint8_t id; /* type */
|
||||
qse_uint8_t type; /* type - 26 */
|
||||
qse_uint8_t length; /* length */
|
||||
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 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_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
|
||||
@ -126,7 +168,7 @@ typedef int (*qse_rad_attr_walker_t) (
|
||||
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_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_ACCT_INTERIM_INTERVAL = 85, /* integer */
|
||||
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
|
||||
{
|
||||
QSE_RAD_ATTR_ACCT_STATUS_TYPE_START = 1, /* accounting start */
|
||||
@ -213,7 +266,22 @@ QSE_EXPORT void qse_rad_initialize (
|
||||
|
||||
QSE_EXPORT qse_rad_attr_hdr_t* qse_rad_find_attribute (
|
||||
qse_rad_hdr_t* hdr,
|
||||
qse_uint8_t attrid,
|
||||
qse_uint8_t attrtype,
|
||||
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
|
||||
);
|
||||
|
||||
@ -238,24 +306,55 @@ QSE_EXPORT int qse_rad_insert_attribute (
|
||||
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_rad_hdr_t* auth,
|
||||
int max,
|
||||
qse_uint32_t vendor,
|
||||
qse_uint8_t attrid,
|
||||
qse_uint8_t attrtype,
|
||||
const void* ptr,
|
||||
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_rad_hdr_t* hdr,
|
||||
qse_uint8_t attrid
|
||||
qse_rad_hdr_t* auth,
|
||||
qse_uint8_t attrtype,
|
||||
int index
|
||||
);
|
||||
|
||||
QSE_EXPORT int qse_rad_delete_vendor_specific_attribute (
|
||||
qse_rad_hdr_t* hdr,
|
||||
qse_rad_hdr_t* auth,
|
||||
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 (
|
||||
@ -318,18 +417,6 @@ QSE_EXPORT int qse_rad_insert_giga_attribute (
|
||||
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_rad_hdr_t* auth,
|
||||
int max,
|
||||
|
@ -1453,7 +1453,6 @@ static int process_attribute (
|
||||
flags.has_tlv = 1;
|
||||
}
|
||||
|
||||
// TODO: what is tlv???
|
||||
if (block_tlv)
|
||||
{
|
||||
/*
|
||||
|
@ -89,52 +89,134 @@ 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;
|
||||
|
||||
while (rem >= QSE_SIZEOF(*attr))
|
||||
{
|
||||
/* sanity checks */
|
||||
if (rem < attr->length) return NULL;
|
||||
if (rem < attr->length) return QSE_NULL;
|
||||
if (attr->length < QSE_SIZEOF(*attr))
|
||||
{
|
||||
/* attribute length cannot be less than the header size.
|
||||
* the packet could be corrupted... */
|
||||
return NULL;
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
rem -= attr->length;
|
||||
if (attr->id == attrid)
|
||||
if (attr->type == attrtype)
|
||||
{
|
||||
*len = rem; /* remaining length */
|
||||
return attr;
|
||||
}
|
||||
|
||||
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length);
|
||||
}
|
||||
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int rem = *len;
|
||||
|
||||
/* xtype must be one of the followings:
|
||||
* 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))
|
||||
{
|
||||
/* sanity checks */
|
||||
if (rem < attr->length) return QSE_NULL;
|
||||
|
||||
/* attribute length cannot be less than the header size.
|
||||
* the packet could be corrupted... */
|
||||
if (attr->length < QSE_SIZEOF(*attr)) goto oops;
|
||||
|
||||
rem -= attr->length;
|
||||
if (attr->type == xtype)
|
||||
{
|
||||
qse_uint8_t xattrtype;
|
||||
|
||||
if (QSE_RAD_ATTR_IS_LONG_EXTENDED(xtype))
|
||||
{
|
||||
qse_rad_lxattr_hdr_t* lxattr;
|
||||
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 (xattrtype == attrtype)
|
||||
{
|
||||
*len = rem;
|
||||
return attr;
|
||||
}
|
||||
|
||||
attr = (qse_rad_attr_hdr_t*) ((char*) attr + attr->length);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length);
|
||||
}
|
||||
|
||||
qse_rad_attr_hdr_t* qse_rad_find_attribute (qse_rad_hdr_t* hdr, qse_uint8_t attrid, int index)
|
||||
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, attrid);
|
||||
attr = find_attribute(attr, &len, attrtype);
|
||||
while (attr)
|
||||
{
|
||||
if (index <= 0) return attr;
|
||||
index--;
|
||||
attr = find_attribute ((qse_rad_attr_hdr_t*)((char*)attr+attr->length), &len, attrid);
|
||||
attr = find_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr+attr->length), &len, attrtype);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
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 attrid, int index)
|
||||
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);
|
||||
@ -146,27 +228,95 @@ qse_rad_attr_hdr_t* qse_rad_find_vendor_specific_attribute (qse_rad_hdr_t* hdr,
|
||||
{
|
||||
vsattr = (qse_rad_vsattr_hdr_t*)attr;
|
||||
|
||||
if (qse_ntoh32(vsattr->vendor) == vendor)
|
||||
if (qse_ntoh32(vsattr->vendor) == vendor && vsattr->vs.type == attrtype)
|
||||
{
|
||||
qse_rad_attr_hdr_t* subattr;
|
||||
int sublen = vsattr->length - QSE_SIZEOF(*vsattr);
|
||||
int val_len;
|
||||
|
||||
if (sublen >= QSE_SIZEOF(*subattr)) /* sanity check */
|
||||
val_len = (int)vsattr->length - QSE_SIZEOF(*vsattr);
|
||||
|
||||
if ((int)vsattr->vs.length == val_len + QSE_SIZEOF(vsattr->vs))
|
||||
{
|
||||
subattr = (qse_rad_attr_hdr_t*)(vsattr + 1);
|
||||
if (subattr->id == attrid && subattr->length == sublen)
|
||||
if (index <= 0) return vsattr;
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attr = find_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length), &len, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (index <= 0) return subattr;
|
||||
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_attribute ((qse_rad_attr_hdr_t*)((char*)attr+attr->length), &len, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||
attr = find_extended_attribute((qse_rad_attr_hdr_t*)((qse_uint8_t*)attr + attr->length), &len, xtype, QSE_RAD_ATTR_VENDOR_SPECIFIC);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
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)
|
||||
@ -192,33 +342,30 @@ int qse_rad_walk_attributes (const qse_rad_hdr_t* hdr, qse_rad_attr_walker_t wal
|
||||
|
||||
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_attr_hdr_t* subattr;
|
||||
int sublen;
|
||||
int val_len;
|
||||
|
||||
if (attr->length < QSE_SIZEOF(*vsattr)) return -1;
|
||||
vsattr = (qse_rad_vsattr_hdr_t*)attr;
|
||||
|
||||
sublen = vsattr->length - QSE_SIZEOF(*vsattr);
|
||||
if (sublen < QSE_SIZEOF(*subattr)) return -1;
|
||||
subattr = (qse_rad_attr_hdr_t*)(vsattr + 1);
|
||||
if (subattr->length != sublen) return -1;
|
||||
val_len = (int)vsattr->length - QSE_SIZEOF(*vsattr);
|
||||
if ((int)vsattr->vs.length != val_len + QSE_SIZEOF(vsattr->vs)) return -1;
|
||||
|
||||
/* if this vendor happens to be 0, walker can't tell
|
||||
* if it is vendor specific or not because 0 is passed in
|
||||
* for non-VSAs. but i don't care. in reality,
|
||||
* 0 is reserved in IANA enterpirse number assignments.
|
||||
* (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
|
||||
{
|
||||
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;
|
||||
@ -239,8 +386,8 @@ int qse_rad_insert_attribute (
|
||||
|
||||
if (new_auth_len > max) return -1;
|
||||
|
||||
attr = (qse_rad_attr_hdr_t*) ((char*)auth + auth_len);
|
||||
attr->id = id;
|
||||
attr = (qse_rad_attr_hdr_t*)((qse_uint8_t*)auth + auth_len);
|
||||
attr->type = id;
|
||||
attr->length = new_auth_len - auth_len;
|
||||
QSE_MEMCPY (attr + 1, ptr, len);
|
||||
auth->length = qse_hton16(new_auth_len);
|
||||
@ -248,36 +395,135 @@ int qse_rad_insert_attribute (
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_rad_insert_vendor_specific_attribute (
|
||||
qse_rad_hdr_t* auth, int max,
|
||||
qse_uint32_t vendor, qse_uint8_t attrid, const void* ptr, qse_uint8_t len)
|
||||
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_rad_vsattr_hdr_t* attr;
|
||||
qse_rad_attr_hdr_t* subattr;
|
||||
qse_rad_xattr_hdr_t* xattr;
|
||||
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 > QSE_RAD_MAX_VSATTR_VALUE_LEN) len = QSE_RAD_MAX_VSATTR_VALUE_LEN;
|
||||
new_auth_len = auth_len + len + QSE_SIZEOF(*attr) + QSE_SIZEOF(*subattr);
|
||||
/*if (len > maxvallen) return -1;*/
|
||||
if (len > maxvallen) len = maxvallen;
|
||||
new_auth_len = auth_len + hdrlen + len;
|
||||
|
||||
if (new_auth_len > max) return -1;
|
||||
|
||||
attr = (qse_rad_vsattr_hdr_t*) ((char*)auth + auth_len);
|
||||
attr->id = QSE_RAD_ATTR_VENDOR_SPECIFIC;
|
||||
attr->length = new_auth_len - auth_len;
|
||||
attr->vendor = qse_hton32 (vendor);
|
||||
xattr = (qse_rad_xattr_hdr_t*)((qse_uint8_t*)auth + auth_len);
|
||||
xattr->type = xtype;
|
||||
xattr->length = new_auth_len - auth_len;
|
||||
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);
|
||||
subattr->id = attrid;
|
||||
subattr->length = len + QSE_SIZEOF(*subattr);
|
||||
QSE_MEMCPY (subattr + 1, ptr, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
qse_uint16_t auth_len;
|
||||
@ -294,28 +540,36 @@ static int delete_attribute (qse_rad_hdr_t* auth, qse_rad_attr_hdr_t* attr)
|
||||
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;
|
||||
|
||||
attr = qse_rad_find_attribute (auth, attrid, 0);
|
||||
if (attr == NULL) return 0; /* not found */
|
||||
attr = qse_rad_find_attribute(auth, attrtype, index);
|
||||
if (!attr) return 0; /* not found */
|
||||
return (delete_attribute(auth, attr) <= -1)? -1: 1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
attr = qse_rad_find_vendor_specific_attribute (auth, vendor, attrid, 0);
|
||||
if (attr == NULL) return 0; /* not found */
|
||||
|
||||
vsattr = (qse_rad_vsattr_hdr_t*)((qse_uint8_t*)attr - QSE_SIZEOF(qse_rad_vsattr_hdr_t));
|
||||
vsattr = qse_rad_find_vsattr(auth, vendor, attrtype, 0);
|
||||
if (!vsattr) return 0; /* not found */
|
||||
return (delete_attribute(auth, (qse_rad_attr_hdr_t*)vsattr) <= -1)? -1: 1;
|
||||
}
|
||||
|
||||
int qse_rad_delete_extended_vendor_specific_attribute (
|
||||
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 (
|
||||
qse_rad_hdr_t* auth, int max, qse_uint32_t vendor,
|
||||
qse_uint8_t id, const qse_mchar_t* value)
|
||||
@ -458,41 +712,6 @@ int qse_rad_insert_giga_attribute (
|
||||
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 ALIGN(x,factor) ((((x) + (factor) - 1) / (factor)) * (factor))
|
||||
|
||||
@ -550,7 +769,13 @@ 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 */
|
||||
if (qse_rad_delete_attribute (auth, QSE_RAD_ATTR_USER_PASSWORD) <= -1) goto oops;
|
||||
while (1)
|
||||
{
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user