eapol_test: Add a universal way of adding extra RADIUS attributes

This change replaces -I and -i options (Chargeable-User-Identity) with a
new -N option that can add any RADIUS attribute into the Access-Request
messages without having to modify eapol_test for each new attribute.
This commit is contained in:
Tomasz Wolniewicz 2009-01-04 22:10:56 +02:00 committed by Jouni Malinen
parent b39d1280a7
commit db803a3607

View file

@ -38,6 +38,13 @@ extern int wpa_debug_show_keys;
struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL };
struct extra_radius_attr {
u8 type;
char syntax;
char *data;
struct extra_radius_attr *next;
};
struct eapol_test_data {
struct wpa_supplicant *wpa_s;
@ -66,8 +73,7 @@ struct eapol_test_data {
char *connect_info;
u8 own_addr[ETH_ALEN];
int cui_flag;
char *cui_str;
struct extra_radius_attr *extra_attrs;
};
static struct eapol_test_data eapol_test;
@ -87,6 +93,69 @@ static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
}
static int add_extra_attr(struct radius_msg *msg,
struct extra_radius_attr *attr)
{
size_t len;
char *pos;
u32 val;
char buf[128];
switch (attr->syntax) {
case 's':
os_snprintf(buf, sizeof(buf), "%s", attr->data);
len = os_strlen(buf);
break;
case 'n':
buf[0] = '\0';
len = 1;
break;
case 'x':
pos = attr->data;
if (pos[0] == '0' && pos[1] == 'x')
pos += 2;
len = os_strlen(pos);
if ((len & 1) || (len / 2) > sizeof(buf)) {
printf("Invalid extra attribute hexstring\n");
return -1;
}
len /= 2;
if (hexstr2bin(pos, (u8 *) buf, len) < 0) {
printf("Invalid extra attribute hexstring\n");
return -1;
}
break;
case 'd':
val = htonl(atoi(attr->data));
os_memcpy(buf, &val, 4);
len = 4;
break;
default:
printf("Incorrect extra attribute syntax specification\n");
return -1;
}
if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) {
printf("Could not add attribute %d\n", attr->type);
return -1;
}
return 0;
}
static int add_extra_attrs(struct radius_msg *msg,
struct extra_radius_attr *attrs)
{
struct extra_radius_attr *p;
for (p = attrs; p; p = p->next) {
if (add_extra_attr(msg, p) < 0)
return -1;
}
return 0;
}
static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
const u8 *eap, size_t len)
{
@ -166,22 +235,8 @@ static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
goto fail;
}
if (e->cui_flag) {
int l = 0;
if (e->cui_flag == 1) {
l = 1;
buf[0] = '\0';
} else if (e->cui_flag == 2) {
os_snprintf(buf, sizeof(buf), "%s", e->cui_str);
l = os_strlen(buf);
}
if (!radius_msg_add_attr(msg,
RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
(u8 *) buf, l)) {
printf("Could not add Chargeable-User-Identity\n");
if (add_extra_attrs(msg, e->extra_attrs) < 0)
goto fail;
}
}
if (eap && !radius_msg_add_eap(msg, eap, len)) {
printf("Could not add EAP-Message\n");
@ -365,6 +420,8 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
static void test_eapol_clean(struct eapol_test_data *e,
struct wpa_supplicant *wpa_s)
{
struct extra_radius_attr *p, *prev;
radius_client_deinit(e->radius);
os_free(e->last_eap_radius);
if (e->last_recv_radius) {
@ -387,6 +444,13 @@ static void test_eapol_clean(struct eapol_test_data *e,
wpa_s->ctrl_iface = NULL;
}
wpa_config_free(wpa_s->conf);
p = e->extra_attrs;
while (p) {
prev = p;
p = p->next;
os_free(prev);
}
}
@ -889,7 +953,8 @@ static void usage(void)
"[-s<AS secret>]\\\n"
" [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
" [-M<client MAC address>] \\\n"
" [-I<CUI>] [-i] [-A<client IP>]\n"
" [-N<attr spec>] \\\n"
" [-A<client IP>]\n"
"eapol_test scard\n"
"eapol_test sim <PIN> <num triplets> [debug]\n"
"\n");
@ -913,9 +978,18 @@ static void usage(void)
" -M<client MAC address> = Set own MAC address "
"(Calling-Station-Id,\n"
" default: 02:00:00:00:00:01)\n"
" -I<CUI> = send Chargeable-User-Identity containing the "
"value of CUI\n"
" -i = send NUL value in Chargeable-User-Identity\n");
" -N<attr spec> = send arbitrary attribute specified by:\n"
" attr_id:syntax:value or attr_id\n"
" attr_id - number id of the attribute\n"
" syntax - one of: s, d, x\n"
" s = string\n"
" d = integer\n"
" x = octet string\n"
" value - attribute value.\n"
" When only attr_id is specified, NULL will be used as "
"value.\n"
" Multiple attributes can be specified by using the "
"option several times.\n");
}
@ -929,6 +1003,8 @@ int main(int argc, char *argv[])
char *cli_addr = NULL;
char *conf = NULL;
int timeout = 30;
char *pos;
struct extra_radius_attr *p = NULL, *p1;
if (os_program_init())
return -1;
@ -943,7 +1019,7 @@ int main(int argc, char *argv[])
wpa_debug_show_keys = 1;
for (;;) {
c = getopt(argc, argv, "a:A:c:C:iI:M:np:r:s:St:W");
c = getopt(argc, argv, "a:A:c:C:M:nN:p:r:s:St:W");
if (c < 0)
break;
switch (c) {
@ -959,13 +1035,6 @@ int main(int argc, char *argv[])
case 'C':
eapol_test.connect_info = optarg;
break;
case 'i':
eapol_test.cui_flag = 1;
break;
case 'I':
eapol_test.cui_flag = 2;
eapol_test.cui_str = optarg;
break;
case 'M':
if (hwaddr_aton(optarg, eapol_test.own_addr)) {
usage();
@ -993,6 +1062,34 @@ int main(int argc, char *argv[])
case 'W':
wait_for_monitor++;
break;
case 'N':
p1 = os_zalloc(sizeof(p1));
if (p1 == NULL)
break;
if (!p)
eapol_test.extra_attrs = p1;
else
p->next = p1;
p = p1;
p->type = atoi(optarg);
pos = os_strchr(optarg, ':');
if (pos == NULL) {
p->syntax = 'n';
p->data = NULL;
break;
}
pos++;
if (pos[0] == '\0' || pos[1] != ':') {
printf("Incorrect format of attribute "
"specification\n");
break;
}
p->syntax = pos[0];
p->data = pos + 2;
break;
default:
usage();
return -1;