|
|
|
@ -409,75 +409,87 @@ static void ieee802_1x_learn_identity(struct hostapd_data *hapd,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
|
|
|
|
struct sta_info *sta,
|
|
|
|
|
const u8 *eap, size_t len)
|
|
|
|
|
static int add_common_radius_sta_attr(struct hostapd_data *hapd,
|
|
|
|
|
struct hostapd_radius_attr *req_attr,
|
|
|
|
|
struct sta_info *sta,
|
|
|
|
|
struct radius_msg *msg)
|
|
|
|
|
{
|
|
|
|
|
struct radius_msg *msg;
|
|
|
|
|
char buf[128];
|
|
|
|
|
struct eapol_state_machine *sm = sta->eapol_sm;
|
|
|
|
|
struct hostapd_radius_attr *attr;
|
|
|
|
|
|
|
|
|
|
if (sm == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ieee802_1x_learn_identity(hapd, sm, eap, len);
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_PORT) &&
|
|
|
|
|
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add NAS-Port");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
|
|
|
|
|
"packet");
|
|
|
|
|
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
|
|
|
|
|
MAC2STR(sta->addr));
|
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
|
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
|
|
|
|
|
(u8 *) buf, os_strlen(buf))) {
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add Calling-Station-Id");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sm->radius_identifier = radius_client_get_id(hapd->radius);
|
|
|
|
|
msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
|
|
|
|
|
sm->radius_identifier);
|
|
|
|
|
if (msg == NULL) {
|
|
|
|
|
printf("Could not create net RADIUS packet\n");
|
|
|
|
|
return;
|
|
|
|
|
if (sta->flags & WLAN_STA_PREAUTH) {
|
|
|
|
|
os_strlcpy(buf, "IEEE 802.11i Pre-Authentication",
|
|
|
|
|
sizeof(buf));
|
|
|
|
|
} else {
|
|
|
|
|
os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
|
|
|
|
|
radius_sta_rate(hapd, sta) / 2,
|
|
|
|
|
(radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
|
|
|
|
|
radius_mode_txt(hapd));
|
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_CONNECT_INFO) &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
|
|
|
|
|
(u8 *) buf, os_strlen(buf))) {
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add Connect-Info");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sm->identity &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
|
|
|
|
|
sm->identity, sm->identity_len)) {
|
|
|
|
|
printf("Could not add User-Name\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
int add_common_radius_attr(struct hostapd_data *hapd,
|
|
|
|
|
struct hostapd_radius_attr *req_attr,
|
|
|
|
|
struct sta_info *sta,
|
|
|
|
|
struct radius_msg *msg)
|
|
|
|
|
{
|
|
|
|
|
char buf[128];
|
|
|
|
|
struct hostapd_radius_attr *attr;
|
|
|
|
|
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_IP_ADDRESS) &&
|
|
|
|
|
hapd->conf->own_ip_addr.af == AF_INET &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
|
|
|
|
|
(u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
|
|
|
|
|
printf("Could not add NAS-IP-Address\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add NAS-IP-Address");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_IPV6
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_IPV6_ADDRESS) &&
|
|
|
|
|
hapd->conf->own_ip_addr.af == AF_INET6 &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
|
|
|
|
|
(u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
|
|
|
|
|
printf("Could not add NAS-IPv6-Address\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add NAS-IPv6-Address");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
#endif /* CONFIG_IPV6 */
|
|
|
|
|
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_IDENTIFIER) &&
|
|
|
|
|
hapd->conf->nas_identifier &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
|
|
|
|
|
(u8 *) hapd->conf->nas_identifier,
|
|
|
|
|
os_strlen(hapd->conf->nas_identifier))) {
|
|
|
|
|
printf("Could not add NAS-Identifier\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_PORT) &&
|
|
|
|
|
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
|
|
|
|
|
printf("Could not add NAS-Port\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add NAS-Identifier");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
|
|
|
|
@ -485,23 +497,75 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
|
|
|
|
wpa_ssid_txt(hapd->conf->ssid.ssid,
|
|
|
|
|
hapd->conf->ssid.ssid_len));
|
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_CALLED_STATION_ID) &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
|
|
|
|
|
(u8 *) buf, os_strlen(buf))) {
|
|
|
|
|
printf("Could not add Called-Station-Id\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add Called-Station-Id");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
|
|
|
|
|
MAC2STR(sta->addr));
|
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
|
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
|
|
|
|
|
(u8 *) buf, os_strlen(buf))) {
|
|
|
|
|
printf("Could not add Calling-Station-Id\n");
|
|
|
|
|
if (!hostapd_config_get_radius_attr(req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_PORT_TYPE) &&
|
|
|
|
|
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
|
|
|
|
|
RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add NAS-Port-Type");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sta && add_common_radius_sta_attr(hapd, req_attr, sta, msg) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
for (attr = req_attr; attr; attr = attr->next) {
|
|
|
|
|
if (!radius_msg_add_attr(msg, attr->type,
|
|
|
|
|
wpabuf_head(attr->val),
|
|
|
|
|
wpabuf_len(attr->val))) {
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add RADIUS "
|
|
|
|
|
"attribute");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
|
|
|
|
struct sta_info *sta,
|
|
|
|
|
const u8 *eap, size_t len)
|
|
|
|
|
{
|
|
|
|
|
struct radius_msg *msg;
|
|
|
|
|
struct eapol_state_machine *sm = sta->eapol_sm;
|
|
|
|
|
|
|
|
|
|
if (sm == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ieee802_1x_learn_identity(hapd, sm, eap, len);
|
|
|
|
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
|
|
|
|
|
"packet");
|
|
|
|
|
|
|
|
|
|
sm->radius_identifier = radius_client_get_id(hapd->radius);
|
|
|
|
|
msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
|
|
|
|
|
sm->radius_identifier);
|
|
|
|
|
if (msg == NULL) {
|
|
|
|
|
printf("Could not create net RADIUS packet\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
|
|
|
|
|
|
|
|
|
|
if (sm->identity &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
|
|
|
|
|
sm->identity, sm->identity_len)) {
|
|
|
|
|
printf("Could not add User-Name\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, sta,
|
|
|
|
|
msg) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* TODO: should probably check MTU from driver config; 2304 is max for
|
|
|
|
|
* IEEE 802.11, but use 1400 to avoid problems with too large packets
|
|
|
|
|
*/
|
|
|
|
@ -512,32 +576,6 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
RADIUS_ATTR_NAS_PORT_TYPE) &&
|
|
|
|
|
!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
|
|
|
|
|
RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
|
|
|
|
|
printf("Could not add NAS-Port-Type\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sta->flags & WLAN_STA_PREAUTH) {
|
|
|
|
|
os_strlcpy(buf, "IEEE 802.11i Pre-Authentication",
|
|
|
|
|
sizeof(buf));
|
|
|
|
|
} else {
|
|
|
|
|
os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
|
|
|
|
|
radius_sta_rate(hapd, sta) / 2,
|
|
|
|
|
(radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
|
|
|
|
|
radius_mode_txt(hapd));
|
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
if (!hostapd_config_get_radius_attr(hapd->conf->radius_auth_req_attr,
|
|
|
|
|
RADIUS_ATTR_CONNECT_INFO) &&
|
|
|
|
|
!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
|
|
|
|
|
(u8 *) buf, os_strlen(buf))) {
|
|
|
|
|
printf("Could not add Connect-Info\n");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (eap && !radius_msg_add_eap(msg, eap, len)) {
|
|
|
|
|
printf("Could not add EAP-Message\n");
|
|
|
|
|
goto fail;
|
|
|
|
@ -579,17 +617,6 @@ static void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (attr = hapd->conf->radius_auth_req_attr; attr; attr = attr->next)
|
|
|
|
|
{
|
|
|
|
|
if (!radius_msg_add_attr(msg, attr->type,
|
|
|
|
|
wpabuf_head(attr->val),
|
|
|
|
|
wpabuf_len(attr->val))) {
|
|
|
|
|
wpa_printf(MSG_ERROR, "Could not add RADIUS "
|
|
|
|
|
"attribute");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|