static int radius_server_reject(struct radius_server_data *data, struct radius_client *client, struct radius_msg *request, struct sockaddr *from, socklen_t fromlen, const char *from_addr, int from_port) { struct radius_msg *msg; int ret = 0; struct eap_hdr eapfail; struct wpabuf *buf; struct radius_hdr *hdr = radius_msg_get_hdr(request); RADIUS_DEBUG("Reject invalid request from %s:%d", from_addr, from_port); msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier); if (msg == NULL) { return -1; } os_memset(&eapfail, 0, sizeof(eapfail)); eapfail.code = EAP_CODE_FAILURE; eapfail.identifier = 0; eapfail.length = host_to_be16(sizeof(eapfail)); if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) { RADIUS_DEBUG("Failed to add EAP-Message attribute"); } if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); radius_msg_free(msg); return -1; } if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, client->shared_secret_len, hdr->authenticator) < 0) { RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); } if (wpa_debug_level <= MSG_MSGDUMP) { radius_msg_dump(msg); } data->counters.access_rejects++; client->counters.access_rejects++; buf = radius_msg_get_buf(msg); if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, (struct sockaddr *) from, sizeof(*from)) < 0) { wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno)); ret = -1; } radius_msg_free(msg); return ret; }
static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, const u8 *eap, size_t len) { struct radius_msg *msg; char buf[128]; const struct eap_hdr *hdr; const u8 *pos; wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " "packet"); e->radius_identifier = radius_client_get_id(e->radius); msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, e->radius_identifier); if (msg == NULL) { printf("Could not create net RADIUS packet\n"); return; } radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e)); hdr = (const struct eap_hdr *) eap; pos = (const u8 *) (hdr + 1); if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE && pos[0] == EAP_TYPE_IDENTITY) { pos++; os_free(e->eap_identity); e->eap_identity_len = len - sizeof(*hdr) - 1; e->eap_identity = os_malloc(e->eap_identity_len); if (e->eap_identity) { os_memcpy(e->eap_identity, pos, e->eap_identity_len); wpa_hexdump(MSG_DEBUG, "Learned identity from " "EAP-Response-Identity", e->eap_identity, e->eap_identity_len); } } if (e->eap_identity && !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, e->eap_identity, e->eap_identity_len)) { printf("Could not add User-Name\n"); goto fail; } if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) && !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, (u8 *) &e->own_ip_addr, 4)) { printf("Could not add NAS-IP-Address\n"); goto fail; } os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, MAC2STR(e->wpa_s->own_addr)); if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID) && !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, (u8 *) buf, os_strlen(buf))) { printf("Could not add Calling-Station-Id\n"); 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 */ if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) && !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { printf("Could not add Framed-MTU\n"); goto fail; } if (!find_extra_attr(e->extra_attrs, 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; } os_snprintf(buf, sizeof(buf), "%s", e->connect_info); if (!find_extra_attr(e->extra_attrs, 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 (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"); goto fail; } /* State attribute must be copied if and only if this packet is * Access-Request reply to the previous Access-Challenge */ if (e->last_recv_radius && radius_msg_get_hdr(e->last_recv_radius)->code == RADIUS_CODE_ACCESS_CHALLENGE) { int res = radius_msg_copy_attr(msg, e->last_recv_radius, RADIUS_ATTR_STATE); if (res < 0) { printf("Could not copy State attribute from previous " "Access-Challenge\n"); goto fail; } if (res > 0) { wpa_printf(MSG_DEBUG, " Copied RADIUS State " "Attribute"); } } radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr); return; fail: radius_msg_free(msg); }
static void ieee802_1x_encapsulate_radius(struct wpa_supplicant *wpa_s, u8 *eap, size_t len) { struct radius_msg *msg; char buf[128]; struct wpa_ssid *ssid = wpa_s->current_ssid; u8 *identity; size_t identity_len; wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " "packet"); wpa_s->radius_identifier = radius_client_get_id(wpa_s); msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, wpa_s->radius_identifier); if (msg == NULL) { printf("Could not create net RADIUS packet\n"); return; } radius_msg_make_authenticator(msg, (u8 *) wpa_s, sizeof(*wpa_s)); if (ssid->anonymous_identity) { identity = ssid->anonymous_identity; identity_len = ssid->anonymous_identity_len; } else { identity = ssid->identity; identity_len = ssid->identity_len; } if (identity && !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, identity, identity_len)) { printf("Could not add User-Name\n"); goto fail; } if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, (u8 *) &wpa_s->own_ip_addr, 4)) { printf("Could not add NAS-IP-Address\n"); goto fail; } snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, MAC2STR(wpa_s->own_addr)); if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, buf, strlen(buf))) { printf("Could not add Calling-Station-Id\n"); 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 */ if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { printf("Could not add Framed-MTU\n"); goto fail; } if (!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; } snprintf(buf, sizeof(buf), "CONNECT 11Mbps 802.11b"); if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, buf, 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; } /* State attribute must be copied if and only if this packet is * Access-Request reply to the previous Access-Challenge */ if (wpa_s->last_recv_radius && wpa_s->last_recv_radius->hdr->code == RADIUS_CODE_ACCESS_CHALLENGE) { int res = radius_msg_copy_attr(msg, wpa_s->last_recv_radius, RADIUS_ATTR_STATE); if (res < 0) { printf("Could not copy State attribute from previous " "Access-Challenge\n"); goto fail; } if (res > 0) { wpa_printf(MSG_DEBUG, " Copied RADIUS State " "Attribute"); } } radius_client_send(wpa_s, msg, RADIUS_AUTH, wpa_s->own_addr); return; fail: radius_msg_free(msg); free(msg); }
static struct radius_msg * radius_server_encapsulate_eap(struct radius_server_data *data, struct radius_client *client, struct radius_session *sess, struct radius_msg *request) { struct radius_msg *msg; int code; unsigned int sess_id; if (sess->eap_if->eapFail) { sess->eap_if->eapFail = FALSE; code = RADIUS_CODE_ACCESS_REJECT; } else if (sess->eap_if->eapSuccess) { sess->eap_if->eapSuccess = FALSE; code = RADIUS_CODE_ACCESS_ACCEPT; } else { sess->eap_if->eapReq = FALSE; code = RADIUS_CODE_ACCESS_CHALLENGE; } msg = radius_msg_new(code, request->hdr->identifier); if (msg == NULL) { RADIUS_DEBUG("Failed to allocate reply message"); return NULL; } sess_id = htonl(sess->sess_id); if (code == RADIUS_CODE_ACCESS_CHALLENGE && !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, (u8 *) &sess_id, sizeof(sess_id))) { RADIUS_DEBUG("Failed to add State attribute"); } if (sess->eap_if->eapReqData && !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), wpabuf_len(sess->eap_if->eapReqData))) { RADIUS_DEBUG("Failed to add EAP-Message attribute"); } if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { int len; if (sess->eap_if->eapKeyDataLen > 64) { len = 32; } else { len = sess->eap_if->eapKeyDataLen / 2; } if (!radius_msg_add_mppe_keys(msg, request->hdr->authenticator, (u8 *) client->shared_secret, client->shared_secret_len, sess->eap_if->eapKeyData + len, len, sess->eap_if->eapKeyData, len)) { RADIUS_DEBUG("Failed to add MPPE key attributes"); } } if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); radius_msg_free(msg); os_free(msg); return NULL; } if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, client->shared_secret_len, request->hdr->authenticator) < 0) { RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); } return msg; }
static struct radius_msg * radius_server_encapsulate_eap(struct radius_server_data *data, struct radius_client *client, struct radius_session *sess, struct radius_msg *request) { struct radius_msg *msg; int code; unsigned int sess_id; struct radius_hdr *hdr = radius_msg_get_hdr(request); if (sess->eap_if->eapFail) { sess->eap_if->eapFail = FALSE; code = RADIUS_CODE_ACCESS_REJECT; } else if (sess->eap_if->eapSuccess) { sess->eap_if->eapSuccess = FALSE; code = RADIUS_CODE_ACCESS_ACCEPT; } else { sess->eap_if->eapReq = FALSE; code = RADIUS_CODE_ACCESS_CHALLENGE; } msg = radius_msg_new(code, hdr->identifier); if (msg == NULL) { RADIUS_DEBUG("Failed to allocate reply message"); return NULL; } sess_id = htonl(sess->sess_id); if (code == RADIUS_CODE_ACCESS_CHALLENGE && !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, (u8 *) &sess_id, sizeof(sess_id))) { RADIUS_DEBUG("Failed to add State attribute"); } if (sess->eap_if->eapReqData && !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), wpabuf_len(sess->eap_if->eapReqData))) { RADIUS_DEBUG("Failed to add EAP-Message attribute"); } if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { int len; #ifdef CONFIG_RADIUS_TEST if (data->dump_msk_file) { FILE *f; char buf[2 * 64 + 1]; f = fopen(data->dump_msk_file, "a"); if (f) { len = sess->eap_if->eapKeyDataLen; if (len > 64) len = 64; len = wpa_snprintf_hex( buf, sizeof(buf), sess->eap_if->eapKeyData, len); buf[len] = '\0'; fprintf(f, "%s\n", buf); fclose(f); } } #endif /* CONFIG_RADIUS_TEST */ if (sess->eap_if->eapKeyDataLen > 64) { len = 32; } else { len = sess->eap_if->eapKeyDataLen / 2; } if (!radius_msg_add_mppe_keys(msg, hdr->authenticator, (u8 *) client->shared_secret, client->shared_secret_len, sess->eap_if->eapKeyData + len, len, sess->eap_if->eapKeyData, len)) { RADIUS_DEBUG("Failed to add MPPE key attributes"); } } if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); radius_msg_free(msg); return NULL; } if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, client->shared_secret_len, hdr->authenticator) < 0) { RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); } return msg; }