static u8 * eap_md5_buildReq(struct eap_sm *sm, void *priv, int id, size_t *reqDataLen) { struct eap_md5_data *data = priv; struct eap_hdr *req; u8 *pos; (void)sm; if (hostapd_get_rand(data->challenge, CHALLENGE_LEN)) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data"); data->state = FAILURE; return NULL; } req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqDataLen, 1 + CHALLENGE_LEN, EAP_CODE_REQUEST, id, &pos); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } *pos++ = CHALLENGE_LEN; memcpy(pos, data->challenge, CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", pos, CHALLENGE_LEN); data->state = CONTINUE; return (u8 *) req; }
static u8 * eap_md5_buildReq(struct eap_sm *sm, void *priv, int id, size_t *reqDataLen) { struct eap_md5_data *data = priv; struct eap_hdr *req; u8 *pos; if (hostapd_get_rand(data->challenge, CHALLENGE_LEN)) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data"); data->state = FAILURE; return NULL; } *reqDataLen = sizeof(*req) + 2 + CHALLENGE_LEN; req = malloc(*reqDataLen); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for " "request"); data->state = FAILURE; return NULL; } req->code = EAP_CODE_REQUEST; req->identifier = id; req->length = htons(*reqDataLen); pos = (u8 *) (req + 1); *pos++ = EAP_TYPE_MD5; *pos++ = CHALLENGE_LEN; memcpy(pos, data->challenge, CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", pos, CHALLENGE_LEN); data->state = CONTINUE; return (u8 *) req; }
static void * eap_sake_init(struct eap_sm *sm) { struct eap_sake_data *data; data = wpa_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = CHALLENGE; if (hostapd_get_rand(&data->session_id, 1)) { wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data"); os_free(data); return NULL; } wpa_printf(MSG_DEBUG, "EAP-SAKE: Initialized Session ID %d", data->session_id); /* TODO: add support for configuring SERVERID */ data->serverid = (u8 *) strdup("hostapd"); if (data->serverid) data->serverid_len = strlen((char *) data->serverid); (void)sm; return data; }
static u8 * eap_sim_build_reauth(struct eap_sm *sm, struct eap_sim_data *data, int id, size_t *reqDataLen) { struct eap_sim_msg *msg; wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Re-authentication"); if (hostapd_get_rand(data->nonce_s, EAP_SIM_NONCE_S_LEN)) return NULL; wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: NONCE_S", data->nonce_s, EAP_SIM_NONCE_S_LEN); eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, data->emsk); eap_sim_derive_keys_reauth(data->counter, sm->identity, sm->identity_len, data->nonce_s, data->mk, data->msk, data->emsk); msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION); if (eap_sim_build_encr(sm, data, msg, data->counter, data->nonce_s)) { eap_sim_msg_free(msg); return NULL; } wpa_printf(MSG_DEBUG, " AT_MAC"); eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); return eap_sim_msg_finish(msg, reqDataLen, data->k_aut, NULL, 0); }
static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, u16 ver) { int i; struct wpa_eapol_ie_parse ie; struct wpa_ptk *ptk; u8 buf[8]; lwip_log("WPA: RX message 1 of 4-Way Handshake from " MACSTR " (ver=%d)\n", MAC2STR(src_addr), ver); os_memset(&ie, 0, sizeof(ie)); if (sm->proto == WPA_PROTO_RSN) { /* RSN: msg 1/4 should contain PMKID for the selected PMK */ const u8 *_buf = (const u8 *) (key + 1); size_t len = WPA_GET_BE16(key->key_data_length); wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len); wpa_supplicant_parse_ies(_buf, len, &ie); if (ie.pmkid) { wpa_hexdump(MSG_DEBUG, "RSN: PMKID from Authenticator", ie.pmkid, PMKID_LEN); } } if (sm->renew_snonce) { if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) { lwip_log("WPA: Failed to get random data for SNonce\n"); return; } sm->renew_snonce = 0; wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", sm->snonce, WPA_NONCE_LEN); } /* Calculate PTK which will be stored as a temporary PTK until it has * been verified when processing message 3/4. */ ptk = &sm->tptk; wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", sm->own_addr, sm->bssid, sm->snonce, key->key_nonce, (u8 *)ptk, sizeof(*ptk)); /* Supplicant: swap tx/rx Mic keys */ os_memcpy(buf, ptk->u.auth.tx_mic_key, 8); os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8); os_memcpy(ptk->u.auth.rx_mic_key, buf, 8); sm->tptk_set = 1; os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN); if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, ptk)) { return; } }
static u8 * eap_leap_process_success(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const u8 *reqData, size_t reqDataLen, size_t *respDataLen) { struct eap_leap_data *data = priv; struct wpa_ssid *config = eap_get_config(sm); const struct eap_hdr *req; struct eap_hdr *resp; u8 *pos; wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Success"); if (data->state != LEAP_WAIT_SUCCESS) { wpa_printf(MSG_INFO, "EAP-LEAP: EAP-Success received in " "unexpected state (%d) - ignored", data->state); ret->ignore = TRUE; return NULL; } req = (const struct eap_hdr *) reqData; *respDataLen = sizeof(struct eap_hdr) + 1 + 3 + LEAP_CHALLENGE_LEN + config->identity_len; resp = malloc(*respDataLen); if (resp == NULL) return NULL; resp->code = EAP_CODE_REQUEST; resp->identifier = req->identifier; resp->length = host_to_be16(*respDataLen); pos = (u8 *) (resp + 1); *pos++ = EAP_TYPE_LEAP; *pos++ = LEAP_VERSION; *pos++ = 0; /* unused */ *pos++ = LEAP_CHALLENGE_LEN; if (hostapd_get_rand(pos, LEAP_CHALLENGE_LEN)) { wpa_printf(MSG_WARNING, "EAP-LEAP: Failed to read random data " "for challenge"); free(resp); ret->ignore = TRUE; return NULL; } memcpy(data->ap_challenge, pos, LEAP_CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge to AP/AS", pos, LEAP_CHALLENGE_LEN); pos += LEAP_CHALLENGE_LEN; memcpy(pos, config->identity, config->identity_len); data->state = LEAP_WAIT_RESPONSE; return (u8 *) resp; }
static u8 * eap_leap_process_success(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const u8 *reqData, size_t *respDataLen) { struct eap_leap_data *data = priv; const struct eap_hdr *req; struct eap_hdr *resp; u8 *pos; const u8 *identity; size_t identity_len; wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Success"); identity = eap_get_config_identity(sm, &identity_len); if (identity == NULL) return NULL; if (data->state != LEAP_WAIT_SUCCESS) { wpa_printf(MSG_INFO, "EAP-LEAP: EAP-Success received in " "unexpected state (%d) - ignored", data->state); ret->ignore = TRUE; return NULL; } req = (const struct eap_hdr *) reqData; resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP, respDataLen, 3 + LEAP_CHALLENGE_LEN + identity_len, EAP_CODE_REQUEST, req->identifier, &pos); if (resp == NULL) return NULL; *pos++ = LEAP_VERSION; *pos++ = 0; /* unused */ *pos++ = LEAP_CHALLENGE_LEN; if (hostapd_get_rand(pos, LEAP_CHALLENGE_LEN)) { wpa_printf(MSG_WARNING, "EAP-LEAP: Failed to read random data " "for challenge"); os_free(resp); ret->ignore = TRUE; return NULL; } os_memcpy(data->ap_challenge, pos, LEAP_CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge to AP/AS", pos, LEAP_CHALLENGE_LEN); pos += LEAP_CHALLENGE_LEN; os_memcpy(pos, identity, identity_len); data->state = LEAP_WAIT_RESPONSE; return (u8 *) resp; }
static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv) { struct eap_sim_data *data = priv; if (hostapd_get_rand(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " "for NONCE_MT"); free(data); return NULL; } data->num_id_req = 0; data->num_notification = 0; data->state = CONTINUE; return priv; }
static void hostapd_set_broadcast_wep(hostapd *hapd) { if (hapd->conf->default_wep_key_len < 1) return; hapd->default_wep_key = malloc(hapd->conf->default_wep_key_len); if (hapd->default_wep_key == NULL || hostapd_get_rand(hapd->default_wep_key, hapd->conf->default_wep_key_len)) { printf("Could not generate random WEP key.\n"); free(hapd->default_wep_key); exit(1); } }
static u8 * eap_pax_build_std_1(struct eap_sm *sm, struct eap_pax_data *data, int id, size_t *reqDataLen) { struct eap_pax_hdr *req; u8 *pos; wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (sending)"); if (hostapd_get_rand(data->rand.r.x, EAP_PAX_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data"); data->state = FAILURE; return NULL; } *reqDataLen = sizeof(*req) + 2 + EAP_PAX_RAND_LEN + EAP_PAX_ICV_LEN; req = VM_MALLOC(*reqDataLen); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory " "request"); data->state = FAILURE; return NULL; } req->code = EAP_CODE_REQUEST; req->identifier = id; req->length = htons(*reqDataLen); req->type = EAP_TYPE_PAX; req->op_code = EAP_PAX_OP_STD_1; req->flags = 0; req->mac_id = data->mac_id; req->dh_group_id = EAP_PAX_DH_GROUP_NONE; req->public_key_id = EAP_PAX_PUBLIC_KEY_NONE; pos = (u8 *) (req + 1); *pos++ = 0; *pos++ = EAP_PAX_RAND_LEN; memcpy(pos, data->rand.r.x, EAP_PAX_RAND_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: A = X (server rand)", pos, EAP_PAX_RAND_LEN); pos += EAP_PAX_RAND_LEN; eap_pax_mac(data->mac_id, (u8 *) "", 0, (u8 *) req, *reqDataLen - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, pos); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN); pos += EAP_PAX_ICV_LEN; return (u8 *) req; }
static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix) { char *id, *pos, *end; u8 buf[10]; if (hostapd_get_rand(buf, sizeof(buf))) return NULL; id = VM_MALLOC(sizeof(buf) * 2 + 2); if (id == NULL) return NULL; pos = id; end = id + sizeof(buf) * 2 + 2; *pos++ = prefix; pos += wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf)); return id; }
static u8 * eap_mschapv2_build_challenge(struct eap_sm *sm, struct eap_mschapv2_data *data, int id, size_t *reqDataLen) { struct eap_hdr *req; struct eap_mschapv2_hdr *ms; u8 *pos; char *name = "hostapd"; /* TODO: make this configurable */ size_t ms_len; if (hostapd_get_rand(data->auth_challenge, CHALLENGE_LEN)) { wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to get random " "data"); data->state = FAILURE; return NULL; } ms_len = sizeof(*ms) + 1 + CHALLENGE_LEN + strlen(name); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqDataLen, ms_len, EAP_CODE_REQUEST, id, &pos); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory" " for request"); data->state = FAILURE; return NULL; } ms = (struct eap_mschapv2_hdr *) pos; ms->op_code = MSCHAPV2_OP_CHALLENGE; ms->mschapv2_id = id; WPA_PUT_BE16(ms->ms_length, ms_len); pos = (u8 *) (ms + 1); *pos++ = CHALLENGE_LEN; memcpy(pos, data->auth_challenge, CHALLENGE_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge", pos, CHALLENGE_LEN); pos += CHALLENGE_LEN; memcpy(pos, name, strlen(name)); return (u8 *) req; }
static u8 * eap_sake_build_challenge(struct eap_sm *sm, struct eap_sake_data *data, int id, size_t *reqDataLen) { u8 *msg, *pos; wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge"); if (hostapd_get_rand(data->rand_s, EAP_SAKE_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data"); data->state = FAILURE; return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)", data->rand_s, EAP_SAKE_RAND_LEN); *reqDataLen = 2 + EAP_SAKE_RAND_LEN; if (data->serverid) *reqDataLen += 2 + data->serverid_len; msg = eap_sake_build_msg(data, &pos, id, reqDataLen, EAP_SAKE_SUBTYPE_CHALLENGE); if (msg == NULL) { data->state = FAILURE; return NULL; } wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_S"); *pos++ = EAP_SAKE_AT_RAND_S; *pos++ = 2 + EAP_SAKE_RAND_LEN; os_memcpy(pos, data->rand_s, EAP_SAKE_RAND_LEN); pos += EAP_SAKE_RAND_LEN; if (data->serverid) { wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_SERVERID"); *pos++ = EAP_SAKE_AT_SERVERID; *pos++ = 2 + data->serverid_len; os_memcpy(pos, data->serverid, data->serverid_len); } (void)sm; return msg; }
int eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv, u8 attr_encr) { u8 *pos = eap_sim_msg_add(msg, attr_iv, 0, NULL, EAP_SIM_IV_LEN); if (pos == NULL) return -1; msg->iv = (pos - msg->buf) + 4; if (hostapd_get_rand(msg->buf + msg->iv, EAP_SIM_IV_LEN)) { msg->iv = 0; return -1; } pos = eap_sim_msg_add(msg, attr_encr, 0, NULL, 0); if (pos == NULL) { msg->iv = 0; return -1; } msg->encr = pos - msg->buf; return 0; }
static void * eap_sim_init(struct eap_sm *sm) { struct eap_sim_data *data; struct wpa_ssid *config = eap_get_config(sm); data = malloc(sizeof(*data)); if (data == NULL) return NULL; memset(data, 0, sizeof(*data)); if (hostapd_get_rand(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " "for NONCE_MT"); free(data); return NULL; } data->min_num_chal = 2; if (config && config->phase1) { char *pos = strstr(config->phase1, "sim_min_num_chal="); if (pos) { data->min_num_chal = atoi(pos + 17); if (data->min_num_chal < 2 || data->min_num_chal > 3) { wpa_printf(MSG_WARNING, "EAP-SIM: Invalid " "sim_min_num_chal configuration " "(%d, expected 2 or 3)", data->min_num_chal); free(data); return NULL; } wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of " "challenges to %d", data->min_num_chal); } } data->state = CONTINUE; return data; }
static u8 * eap_sake_process_challenge(struct eap_sm *sm, struct eap_sake_data *data, struct eap_method_ret *ret, const u8 *reqData, size_t reqDataLen, const u8 *payload, size_t payload_len, size_t *respDataLen) { struct eap_sake_parse_attr attr; u8 *resp, *rpos; const struct eap_hdr *hdr = (const struct eap_hdr *) reqData; if (data->state != IDENTITY && data->state != CHALLENGE) { wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge received " "in unexpected state (%d)", data->state); ret->ignore = TRUE; return NULL; } if (data->state == IDENTITY) eap_sake_state(data, CHALLENGE); wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Challenge"); if (eap_sake_parse_attributes(payload, payload_len, &attr)) return NULL; if (!attr.rand_s) { wpa_printf(MSG_INFO, "EAP-SAKE: Request/Challenge did not " "include AT_RAND_S"); return NULL; } os_memcpy(data->rand_s, attr.rand_s, EAP_SAKE_RAND_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)", data->rand_s, EAP_SAKE_RAND_LEN); if (hostapd_get_rand(data->rand_p, EAP_SAKE_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data"); return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_P (peer rand)", data->rand_p, EAP_SAKE_RAND_LEN); os_free(data->serverid); data->serverid = NULL; data->serverid_len = 0; if (attr.serverid) { wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-SAKE: SERVERID", attr.serverid, attr.serverid_len); data->serverid = os_malloc(attr.serverid_len); if (data->serverid == NULL) return NULL; os_memcpy(data->serverid, attr.serverid, attr.serverid_len); data->serverid_len = attr.serverid_len; } eap_sake_derive_keys(data->root_secret_a, data->root_secret_b, data->rand_s, data->rand_p, (u8 *) &data->tek, data->msk, data->emsk); wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Challenge"); *respDataLen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN; if (data->peerid) *respDataLen += 2 + data->peerid_len; resp = eap_sake_build_msg(data, &rpos, hdr->identifier, respDataLen, EAP_SAKE_SUBTYPE_CHALLENGE); if (resp == NULL) return NULL; wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_P"); *rpos++ = EAP_SAKE_AT_RAND_P; *rpos++ = 2 + EAP_SAKE_RAND_LEN; os_memcpy(rpos, data->rand_p, EAP_SAKE_RAND_LEN); rpos += EAP_SAKE_RAND_LEN; if (data->peerid) { wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID"); *rpos++ = EAP_SAKE_AT_PEERID; *rpos++ = 2 + data->peerid_len; os_memcpy(rpos, data->peerid, data->peerid_len); rpos += data->peerid_len; } wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P"); *rpos++ = EAP_SAKE_AT_MIC_P; *rpos++ = 2 + EAP_SAKE_MIC_LEN; if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p, data->serverid, data->serverid_len, data->peerid, data->peerid_len, 1, resp, *respDataLen, rpos, rpos)) { wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC"); os_free(resp); return NULL; } eap_sake_state(data, CONFIRM); return resp; }
struct rtapd_config * Config_read(int ioctl_sock, char *prefix_name) { struct rtapd_config *conf; int errors = 0, i = 0; int flag = 0; conf = malloc(sizeof(*conf)); if (conf == NULL) { DBGPRINT(RT_DEBUG_TRACE, "Failed to allocate memory for configuration data.\n"); return NULL; } memset(conf, 0, sizeof(*conf)); conf->SsidNum = 1; conf->session_timeout_set = 0xffff; /* Some related variable per BSS set to default */ for (i = 0; i < MAX_MBSSID_NUM; i++) { /* initial default shared-key material and index */ conf->DefaultKeyID[i] = 0; // broadcast key index conf->individual_wep_key_idx[i] = 3; // unicast key index conf->individual_wep_key_len[i] = WEP8021X_KEY_LEN; // key length hostapd_get_rand(conf->IEEE8021X_ikey[i], WEP8021X_KEY_LEN); // generate shared key randomly /* Initial NAS-ID */ memcpy(conf->nasId[i], "RalinkAP", 8); conf->nasId[i][8] = '0' + i; conf->nasId_len[i] = 9; } // initial default EAP IF name and Pre-Auth IF name as "br0" conf->num_eap_if = 1; conf->num_preauth_if = 1; strcpy(conf->eap_if_name[0], "br0"); strcpy(conf->preauth_if_name[0], "br0"); // Get parameters from deiver through IOCTL cmd if(!Query_config_from_driver(ioctl_sock, prefix_name, conf, &errors, &flag)) { Config_free(conf); return NULL; } #if MULTIPLE_RADIUS for (i = 0; i < MAX_MBSSID_NUM; i++) { struct hostapd_radius_server *servs, *cserv, *nserv; int c; conf->mbss_auth_server[i] = conf->mbss_auth_servers[i]; if (!conf->mbss_auth_server[i]) continue; cserv = conf->mbss_auth_server[i]; servs = conf->mbss_auth_servers[i]; DBGPRINT(RT_DEBUG_TRACE, "%s%d, Current IP: %s \n", prefix_name, i, inet_ntoa(cserv->addr)); for (c = 0; c < conf->mbss_num_auth_servers[i]; c++) { nserv = &servs[c]; DBGPRINT(RT_DEBUG_TRACE, " Server IP List: %s \n", inet_ntoa(nserv->addr)); } } #else conf->auth_server = conf->auth_servers; #endif if (errors) { DBGPRINT(RT_DEBUG_ERROR,"%d errors for radius setting\n", errors); Config_free(conf); conf = NULL; } if ((flag&0x0f)!=0x0f) { DBGPRINT(RT_DEBUG_ERROR,"Not enough necessary parameters are found, flag = %x\n", flag); Config_free(conf); conf = NULL; } return conf; }
static u8 * eap_mschapv2_change_password(struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, size_t *respDataLen) { struct eap_mschapv2_hdr *resp; int ms_len; u8 *peer_challenge, *username, *pos; size_t i, username_len; struct wpa_ssid *config = eap_get_config(sm); if (config == NULL || config->identity == NULL || config->new_password == NULL || config->password == NULL) return NULL; /* * MSCHAPv2 does not include optional domain name in the * challenge-response calculation, so remove domain prefix * (if present). */ username = config->identity; username_len = config->identity_len; for (i = 0; i < username_len; i++) { if (username[i] == '\\') { username_len -= i + 1; username += i + 1; break; } } ret->ignore = FALSE; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_COND_SUCC; ret->allowNotifications = TRUE; *respDataLen = 591; resp = malloc(*respDataLen); if (resp == NULL) { return NULL; } resp->code = EAP_CODE_RESPONSE; resp->identifier = req->identifier; resp->length = host_to_be16((u16) *respDataLen); resp->type = EAP_TYPE_MSCHAPV2; resp->op_code = MSCHAPV2_OP_CHANGE_PASSWORD; resp->mschapv2_id = req->mschapv2_id + 1; ms_len = *respDataLen - 5; WPA_PUT_BE16(resp->ms_length, ms_len); pos = (u8 *) (resp + 1); /* Encrypted-Password */ new_password_encrypted_with_old_nt_password_hash( config->new_password, config->new_password_len, config->password, config->password_len, pos); pos += 516; /* Encrypted-Hash */ old_nt_password_hash_encrypted_with_new_nt_password_hash( config->new_password, config->new_password_len, config->password, config->password_len, pos); pos += 16; /* Peer-Challenge */ peer_challenge = pos; if (hostapd_get_rand(peer_challenge, 16)) { free(resp); return NULL; } pos += 16; /* Reserved, must be zero */ memset(pos, 0, 8); pos += 8; /* NT-Response */ wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge", data->passwd_change_challenge, PASSWD_CHANGE_CHAL_LEN); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge", peer_challenge, 16); wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: username", username, username_len); wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: new password", config->new_password, config->new_password_len); generate_nt_response(data->passwd_change_challenge, peer_challenge, username, username_len, config->new_password, config->new_password_len, pos); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: NT-Response", pos, 24); /* Authenticator response is not really needed yet, but calculate it * here so that challenges need not be saved. */ generate_authenticator_response(config->new_password, config->new_password_len, peer_challenge, data->passwd_change_challenge, username, username_len, pos, data->auth_response); data->auth_response_valid = 1; pos += 24; /* Flags */ *pos++ = 0; *pos++ = 0; wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d " "(change pw)", resp->identifier, resp->mschapv2_id); return (u8 *) resp; }
static u8 * eap_mschapv2_challenge(struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, size_t *respDataLen) { u8 *challenge, *peer_challenge, *pos; int ms_len; size_t i, len, challenge_len, username_len, identity_len, password_len; struct eap_mschapv2_hdr *resp; u8 password_hash[16], password_hash_hash[16]; const u8 *username, *identity, *password; identity = eap_get_config_identity(sm, &identity_len); password = eap_get_config_password(sm, &password_len); if (identity == NULL || password == NULL) return NULL; /* MSCHAPv2 does not include optional domain name in the * challenge-response calculation, so remove domain prefix * (if present). */ username = identity; username_len = identity_len; for (i = 0; i < username_len; i++) { if (username[i] == '\\') { username_len -= i + 1; username += i + 1; break; } } wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received challenge"); len = be_to_host16(req->length); pos = (u8 *) (req + 1); challenge_len = *pos++; if (challenge_len != 16) { wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid challenge length " "%lu", (unsigned long) challenge_len); ret->ignore = TRUE; return NULL; } if (len < 10 || len - 10 < challenge_len) { wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge" " packet: len=%lu challenge_len=%lu", (unsigned long) len, (unsigned long) challenge_len); ret->ignore = TRUE; return NULL; } if (data->passwd_change_challenge_valid) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Using challenge from the " "failure message"); challenge = data->passwd_change_challenge; } else challenge = pos; pos += challenge_len; wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Authentication Servername", pos, len - challenge_len - 10); ret->ignore = FALSE; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; ret->allowNotifications = TRUE; wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Generating Challenge Response"); *respDataLen = sizeof(*resp) + 1 + MSCHAPV2_RESP_LEN + identity_len; resp = wpa_zalloc(*respDataLen); if (resp == NULL) return NULL; resp->code = EAP_CODE_RESPONSE; resp->identifier = req->identifier; resp->length = host_to_be16(*respDataLen); resp->type = EAP_TYPE_MSCHAPV2; resp->op_code = MSCHAPV2_OP_RESPONSE; resp->mschapv2_id = req->mschapv2_id; if (data->prev_error) { /* * TODO: this does not seem to be enough when processing two * or more failure messages. IAS did not increment mschapv2_id * in its own packets, but it seemed to expect the peer to * increment this for all packets(?). */ resp->mschapv2_id++; } ms_len = *respDataLen - 5; WPA_PUT_BE16(resp->ms_length, ms_len); pos = (u8 *) (resp + 1); *pos++ = MSCHAPV2_RESP_LEN; /* Value-Size */ /* Response */ peer_challenge = pos; if (data->peer_challenge) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge generated " "in Phase 1"); peer_challenge = data->peer_challenge; } else if (hostapd_get_rand(peer_challenge, 16)) { free(resp); return NULL; } pos += 16; pos += 8; /* Reserved, must be zero */ if (data->auth_challenge) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge generated " "in Phase 1"); challenge = data->auth_challenge; } wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge", challenge, 16); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge", peer_challenge, 16); wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: username", username, username_len); wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: password", password, password_len); generate_nt_response(challenge, peer_challenge, username, username_len, password, password_len, pos); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: response", pos, 24); /* Authenticator response is not really needed yet, but calculate it * here so that challenges need not be saved. */ generate_authenticator_response(password, password_len, peer_challenge, challenge, username, username_len, pos, data->auth_response); data->auth_response_valid = 1; /* Likewise, generate master_key here since we have the needed data * available. */ nt_password_hash(password, password_len, password_hash); hash_nt_password_hash(password_hash, password_hash_hash); get_master_key(password_hash_hash, pos /* nt_response */, data->master_key); data->master_key_valid = 1; pos += 24; pos++; /* Flag / reserved, must be zero */ memcpy(pos, identity, identity_len); wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d " "(response)", resp->identifier, resp->mschapv2_id); return (u8 *) resp; }
static u8 * eap_mschapv2_challenge(struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_method_ret *ret, struct eap_mschapv2_hdr *req, size_t *respDataLen) { struct wpa_ssid *config = eap_get_config(sm); u8 *challenge, *peer_challenge, *username, *pos; int challenge_len, i, ms_len; size_t len, username_len; struct eap_mschapv2_hdr *resp; u8 password_hash[16], password_hash_hash[16]; /* MSCHAPv2 does not include optional domain name in the * challenge-response calculation, so remove domain prefix * (if present). */ username = config->identity; username_len = config->identity_len; for (i = 0; i < username_len; i++) { if (username[i] == '\\') { username_len -= i + 1; username += i + 1; break; } } wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received challenge"); len = be_to_host16(req->length); pos = (u8 *) (req + 1); challenge_len = *pos++; if (challenge_len != 16) { wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid challenge length " "%d", challenge_len); ret->ignore = TRUE; return NULL; } if (len - challenge_len - 10 < 0) { wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge" " packet: len=%lu challenge_len=%d", (unsigned long) len, challenge_len); } challenge = pos; pos += challenge_len; wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Authentication Servername", pos, len - challenge_len - 10); ret->ignore = FALSE; ret->methodState = METHOD_CONT; ret->decision = DECISION_FAIL; ret->allowNotifications = TRUE; wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Generating Challenge Response"); *respDataLen = sizeof(*resp) + 1 + MSCHAPV2_RESP_LEN + config->identity_len; resp = malloc(*respDataLen); if (resp == NULL) return NULL; memset(resp, 0, *respDataLen); resp->code = EAP_CODE_RESPONSE; resp->identifier = req->identifier; resp->length = host_to_be16(*respDataLen); resp->type = EAP_TYPE_MSCHAPV2; resp->op_code = MSCHAPV2_OP_RESPONSE; resp->mschapv2_id = req->mschapv2_id; ms_len = *respDataLen - 5; resp->ms_length[0] = ms_len >> 8; resp->ms_length[1] = ms_len & 0xff; pos = (u8 *) (resp + 1); *pos++ = MSCHAPV2_RESP_LEN; /* Value-Size */ /* Response */ peer_challenge = pos; if (data->peer_challenge) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge generated " "in Phase 1"); peer_challenge = data->peer_challenge; } else if (hostapd_get_rand(peer_challenge, 16)) { free(resp); return NULL; } pos += 16; pos += 8; /* Reserved, must be zero */ if (data->auth_challenge) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge generated " "in Phase 1"); challenge = data->auth_challenge; } wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge", challenge, 16); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge", peer_challenge, 16); wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: username", username, username_len); wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: password", config->password, config->password_len); generate_nt_response(challenge, peer_challenge, username, username_len, config->password, config->password_len, pos); wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: response", pos, 24); /* Authenticator response is not really needed yet, but calculate it * here so that challenges need not be saved. */ generate_authenticator_response(config->password, config->password_len, peer_challenge, challenge, username, username_len, pos, data->auth_response); data->auth_response_valid = 1; /* Likewise, generate master_key here since we have the needed data * available. */ nt_password_hash(config->password, config->password_len, password_hash); hash_nt_password_hash(password_hash, password_hash_hash); get_master_key(password_hash_hash, pos /* nt_response */, data->master_key); data->master_key_valid = 1; pos += 24; pos++; /* Flag / reserved, must be zero */ memcpy(pos, config->identity, config->identity_len); return (u8 *) resp; }
int32 sslGetEntropy(unsigned char *bytes, int32 size) { #if 0 int32 rc, sanity, retry, readBytes; unsigned char *where = bytes; sanity = retry = rc = readBytes = 0; while (size) { if ((rc = read(randfd, where, size)) < 0 || sanity > MAX_RAND_READS) { if (errno == EINTR) { if (sanity > MAX_RAND_READS) { return -1; } sanity++; continue; } else if (errno == EAGAIN) { break; } else if (errno == EBADF && retry == 0) { close(randfd); if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0) { break; } retry++; continue; } else { break; } } readBytes += rc; where += rc; size -= rc; } sanity = retry = 0; while (size) { if ((rc = read(urandfd, where, size)) < 0 || sanity > MAX_RAND_READS) { if (errno == EINTR) { if (sanity > MAX_RAND_READS) { return -1; } sanity++; continue; } else if (errno == EBADF && retry == 0) { close(urandfd); if ((urandfd = open("/dev/urandom", O_RDONLY | O_NONBLOCK)) < 0) { return -1; } retry++; continue; } else { return -1; } } readBytes += rc; where += rc; size -= rc; } return readBytes; #endif return hostapd_get_rand(bytes, size); }