This commit was generated by cvs2svn to compensate for changes in r147338,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Sam Leffler 2005-06-13 16:43:14 +00:00
commit f59037e440
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147339
18 changed files with 1546 additions and 37 deletions

View File

@ -1,5 +1,28 @@
ChangeLog for wpa_supplicant
2005-06-10 - v0.3.9
* modified the EAP workaround that accepts EAP-Success with incorrect
Identifier to be even less strict about verification in order to
interoperate with some authentication servers
* fixed RSN IE in 4-Way Handshake message 2/4 for the case where
Authenticator rejects PMKSA caching attempt and the driver is not
using assoc_info events
* fixed a possible double free in EAP-TTLS fast-reauthentication when
identity or password is entered through control interface
* added -P<pid file> argument for wpa_supplicant to write the current
process id into a file
* driver_madwifi: fixed association in plaintext mode
* driver_madwifi: added preliminary support for compiling against 'BSD'
branch of madwifi CVS tree
* added EAP workaround for PEAPv1 session resumption: allow outer,
i.e., not tunneled, EAP-Success to terminate session since; this can
be disabled with eap_workaround=0
* driver_ipw: updated driver structures to match with ipw2200-1.0.4
(note: ipw2100-1.1.0 is likely to require an update to work with
this)
* driver_broadcom: fixed couple of memory leaks in scan result
processing
2005-02-13 - v0.3.8
* fixed EAPOL-Key validation to drop packets with invalid Key Data
Length; such frames could have crashed wpa_supplicant due to buffer

View File

@ -6,9 +6,7 @@ contributors
All Rights Reserved.
This program is dual-licensed under both the GPL version 2 and BSD
license. Either license may be used at your option. Please note that
some of the driver interface implementations (driver_*.c) may be
licensed under a different license.
license. Either license may be used at your option.

View File

@ -245,7 +245,7 @@ static int wpa_config_parse_proto(struct parse_data *data, int line,
return -1;
start = buf;
while (start != '\0') {
while (*start != '\0') {
while (*start == ' ' || *start == '\t')
start++;
if (*start == '\0')
@ -295,7 +295,7 @@ static int wpa_config_parse_key_mgmt(struct parse_data *data, int line,
return -1;
start = buf;
while (start != '\0') {
while (*start != '\0') {
while (*start == ' ' || *start == '\t')
start++;
if (*start == '\0')
@ -349,7 +349,7 @@ static int wpa_config_parse_cipher(int line, const char *value)
return -1;
start = buf;
while (start != '\0') {
while (*start != '\0') {
while (*start == ' ' || *start == '\t')
start++;
if (*start == '\0')
@ -441,7 +441,7 @@ static int wpa_config_parse_auth_alg(struct parse_data *data, int line,
return -1;
start = buf;
while (start != '\0') {
while (*start != '\0') {
while (*start == ' ' || *start == '\t')
start++;
if (*start == '\0')
@ -494,7 +494,7 @@ static int wpa_config_parse_eap(struct parse_data *data, int line,
return -1;
start = buf;
while (start != '\0') {
while (*start != '\0') {
while (*start == ' ' || *start == '\t')
start++;
if (*start == '\0')

View File

@ -248,8 +248,9 @@ static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
return -1;
*pos++ = '\0';
id = atoi(id_pos);
wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d value='%s'",
rsp, id, pos);
wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
(u8 *) pos, strlen(pos));
ssid = wpa_s->conf->ssid;
while (ssid) {
@ -606,6 +607,16 @@ void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s)
if (wpa_s->ctrl_sock > -1) {
char *fname;
eloop_unregister_read_sock(wpa_s->ctrl_sock);
if (wpa_s->ctrl_dst) {
/*
* Wait a second before closing the control socket if
* there are any attached monitors in order to allow
* them to receive any pending messages.
*/
wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
"monitors to receive messages");
sleep(1);
}
close(wpa_s->ctrl_sock);
wpa_s->ctrl_sock = -1;
fname = wpa_supplicant_ctrl_iface_path(wpa_s);

View File

@ -458,19 +458,27 @@ SM_STATE(EAP, FAILURE)
static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId)
{
/* At least Microsoft IAS and Meetinghouse Aegis seem to be sending
/*
* At least Microsoft IAS and Meetinghouse Aegis seem to be sending
* EAP-Success/Failure with lastId + 1 even though RFC 3748 and
* draft-ietf-eap-statemachine-05.pdf require that reqId == lastId.
* In addition, it looks like Ringmaster v2.1.2.0 would be using
* lastId + 2 in EAP-Success.
*
* Accept this kind of Id if EAP workarounds are enabled. These are
* unauthenticated plaintext messages, so this should have minimal
* security implications (bit easier to fake EAP-Success/Failure). */
if (sm->workaround && reqId == ((lastId + 1) & 0xff)) {
* security implications (bit easier to fake EAP-Success/Failure).
*/
if (sm->workaround && (reqId == ((lastId + 1) & 0xff) ||
reqId == ((lastId + 2) & 0xff))) {
wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected "
"identifier field in EAP Success: "
"reqId=%d lastId=%d (these are supposed to be "
"same)", reqId, lastId);
return 1;
}
wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d "
"lastId=%d", reqId, lastId);
return 0;
}

View File

@ -126,8 +126,8 @@ static u8 * eap_mschapv2_challenge(struct eap_sm *sm,
{
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;
int i, ms_len;
size_t len, challenge_len, username_len;
struct eap_mschapv2_hdr *resp;
u8 password_hash[16], password_hash_hash[16];
@ -155,10 +155,12 @@ static u8 * eap_mschapv2_challenge(struct eap_sm *sm,
return NULL;
}
if (len - challenge_len - 10 < 0) {
if (len < 10 || len - 10 < challenge_len) {
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge"
" packet: len=%lu challenge_len=%d",
(unsigned long) len, challenge_len);
ret->ignore = TRUE;
return NULL;
}
challenge = pos;
@ -469,7 +471,8 @@ static u8 * eap_mschapv2_process(struct eap_sm *sm, void *priv,
req = (struct eap_mschapv2_hdr *) reqData;
len = be_to_host16(req->length);
if (len < sizeof(*req) + 2 || req->type != EAP_TYPE_MSCHAPV2) {
if (len < sizeof(*req) + 2 || req->type != EAP_TYPE_MSCHAPV2 ||
len > reqDataLen) {
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid frame");
ret->ignore = TRUE;
return NULL;

View File

@ -380,6 +380,12 @@ static int eap_peap_decrypt(struct eap_sm *sm,
if (data->pending_phase2_req) {
wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 request - "
"skip decryption and use old data");
/* Clear TLS reassembly state. */
free(data->ssl.tls_in);
data->ssl.tls_in = NULL;
data->ssl.tls_in_len = 0;
data->ssl.tls_in_left = 0;
data->ssl.tls_in_total = 0;
in_decrypted = data->pending_phase2_req;
data->pending_phase2_req = NULL;
len_decrypted = data->pending_phase2_req_len;
@ -391,6 +397,19 @@ static int eap_peap_decrypt(struct eap_sm *sm,
if (res < 0 || res == 1)
return res;
if (in_len == 0 && sm->workaround && data->phase2_success) {
/*
* Cisco ACS seems to be using TLS ACK to terminate
* EAP-PEAPv0/GTC. Try to reply with TLS ACK.
*/
wpa_printf(MSG_DEBUG, "EAP-PEAP: Received TLS ACK, but "
"expected data - acknowledge with TLS ACK since "
"Phase 2 has been completed");
ret->decision = DECISION_COND_SUCC;
ret->methodState = METHOD_DONE;
return 1;
}
buf_len = in_len;
if (data->ssl.tls_in_total > buf_len)
buf_len = data->ssl.tls_in_total;
@ -713,6 +732,25 @@ static u8 * eap_peap_process(struct eap_sm *sm, void *priv,
wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to "
"derive key");
}
if (sm->workaround && data->peap_version == 1 &&
data->resuming) {
/*
* At least one RADIUS server (Aegis v1.1.6;
* but not v1.1.4) seems to be terminating
* PEAPv1 session resumption with outer
* EAP-Success. This does not seem to follow
* draft-josefsson-pppext-eap-tls-eap-05.txt
* section 4.2, so only allow this if EAP
* workarounds are enabled.
*/
wpa_printf(MSG_DEBUG, "EAP-PEAP: Workaround - "
"allow outer EAP-Success to "
"terminate PEAPv1 resumption");
ret->decision = DECISION_COND_SUCC;
data->phase2_success = 1;
}
data->resuming = 0;
}
}

View File

@ -160,6 +160,17 @@ int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data,
u8 *buf;
if (data->tls_in_left > *in_len || data->tls_in) {
if (data->tls_in_len + *in_len == 0) {
free(data->tls_in);
data->tls_in = NULL;
data->tls_in_len = 0;
wpa_printf(MSG_WARNING, "SSL: Invalid reassembly "
"state: tls_in_left=%d tls_in_len=%d "
"*in_len=%d",
data->tls_in_left, data->tls_in_len,
*in_len);
return -1;
}
buf = realloc(data->tls_in, data->tls_in_len + *in_len);
if (buf == NULL) {
free(data->tls_in);

View File

@ -194,7 +194,7 @@ static int eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
* add TLS Message Length field, if the frame is fragmented. */
resp = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
if (resp == NULL)
return 0;
return -1;
resp->code = EAP_CODE_RESPONSE;
resp->identifier = id;
@ -210,7 +210,7 @@ static int eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
"data");
free(resp);
return 0;
return -1;
}
*out_len = sizeof(struct eap_hdr) + 2 + res;
@ -265,6 +265,7 @@ static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
if (avp == NULL) {
free(*resp);
*resp = NULL;
*resp_len = 0;
return -1;
}
@ -782,6 +783,13 @@ static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
if (data->pending_phase2_req) {
wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
"skip decryption and use old data");
/* Clear TLS reassembly state. */
free(data->ssl.tls_in);
data->ssl.tls_in = NULL;
data->ssl.tls_in_len = 0;
data->ssl.tls_in_left = 0;
data->ssl.tls_in_total = 0;
in_decrypted = data->pending_phase2_req;
data->pending_phase2_req = NULL;
len_decrypted = data->pending_phase2_req_len;

View File

@ -194,9 +194,8 @@ static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
"heldWhile=%d startWhen=%d idleWhile=%d",
sm->authWhile, sm->heldWhile, sm->startWhen, sm->idleWhile);
eapol_sm_step(sm);
eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, sm);
eapol_sm_step(sm);
}

View File

@ -158,12 +158,14 @@ void get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
};
const unsigned char *addr[3];
const size_t len[3] = { 16, 24, sizeof(magic1) };
u8 hash[SHA1_MAC_LEN];
addr[0] = password_hash_hash;
addr[1] = nt_response;
addr[2] = magic1;
sha1_vector(3, addr, len, master_key);
sha1_vector(3, addr, len, hash);
memcpy(master_key, hash, 16);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,224 @@
#ifndef RADIUS_H
#define RADIUS_H
/* RFC 2865 - RADIUS */
struct radius_hdr {
u8 code;
u8 identifier;
u16 length; /* including this header */
u8 authenticator[16];
/* followed by length-20 octets of attributes */
} __attribute__ ((packed));
enum { RADIUS_CODE_ACCESS_REQUEST = 1,
RADIUS_CODE_ACCESS_ACCEPT = 2,
RADIUS_CODE_ACCESS_REJECT = 3,
RADIUS_CODE_ACCOUNTING_REQUEST = 4,
RADIUS_CODE_ACCOUNTING_RESPONSE = 5,
RADIUS_CODE_ACCESS_CHALLENGE = 11,
RADIUS_CODE_STATUS_SERVER = 12,
RADIUS_CODE_STATUS_CLIENT = 13,
RADIUS_CODE_RESERVED = 255
};
struct radius_attr_hdr {
u8 type;
u8 length; /* including this header */
/* followed by length-2 octets of attribute value */
} __attribute__ ((packed));
#define RADIUS_MAX_ATTR_LEN (255 - sizeof(struct radius_attr_hdr))
enum { RADIUS_ATTR_USER_NAME = 1,
RADIUS_ATTR_USER_PASSWORD = 2,
RADIUS_ATTR_NAS_IP_ADDRESS = 4,
RADIUS_ATTR_NAS_PORT = 5,
RADIUS_ATTR_FRAMED_MTU = 12,
RADIUS_ATTR_STATE = 24,
RADIUS_ATTR_CLASS = 25,
RADIUS_ATTR_VENDOR_SPECIFIC = 26,
RADIUS_ATTR_SESSION_TIMEOUT = 27,
RADIUS_ATTR_IDLE_TIMEOUT = 28,
RADIUS_ATTR_TERMINATION_ACTION = 29,
RADIUS_ATTR_CALLED_STATION_ID = 30,
RADIUS_ATTR_CALLING_STATION_ID = 31,
RADIUS_ATTR_NAS_IDENTIFIER = 32,
RADIUS_ATTR_ACCT_STATUS_TYPE = 40,
RADIUS_ATTR_ACCT_DELAY_TIME = 41,
RADIUS_ATTR_ACCT_INPUT_OCTETS = 42,
RADIUS_ATTR_ACCT_OUTPUT_OCTETS = 43,
RADIUS_ATTR_ACCT_SESSION_ID = 44,
RADIUS_ATTR_ACCT_AUTHENTIC = 45,
RADIUS_ATTR_ACCT_SESSION_TIME = 46,
RADIUS_ATTR_ACCT_INPUT_PACKETS = 47,
RADIUS_ATTR_ACCT_OUTPUT_PACKETS = 48,
RADIUS_ATTR_ACCT_TERMINATE_CAUSE = 49,
RADIUS_ATTR_ACCT_MULTI_SESSION_ID = 50,
RADIUS_ATTR_ACCT_LINK_COUNT = 51,
RADIUS_ATTR_ACCT_INPUT_GIGAWORDS = 52,
RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS = 53,
RADIUS_ATTR_EVENT_TIMESTAMP = 55,
RADIUS_ATTR_NAS_PORT_TYPE = 61,
RADIUS_ATTR_CONNECT_INFO = 77,
RADIUS_ATTR_EAP_MESSAGE = 79,
RADIUS_ATTR_MESSAGE_AUTHENTICATOR = 80,
RADIUS_ATTR_ACCT_INTERIM_INTERVAL = 85
};
/* Termination-Action */
#define RADIUS_TERMINATION_ACTION_DEFAULT 0
#define RADIUS_TERMINATION_ACTION_RADIUS_REQUEST 1
/* NAS-Port-Type */
#define RADIUS_NAS_PORT_TYPE_IEEE_802_11 19
/* Acct-Status-Type */
#define RADIUS_ACCT_STATUS_TYPE_START 1
#define RADIUS_ACCT_STATUS_TYPE_STOP 2
#define RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE 3
#define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON 7
#define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF 8
/* Acct-Authentic */
#define RADIUS_ACCT_AUTHENTIC_RADIUS 1
#define RADIUS_ACCT_AUTHENTIC_LOCAL 2
#define RADIUS_ACCT_AUTHENTIC_REMOTE 3
/* Acct-Terminate-Cause */
#define RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST 1
#define RADIUS_ACCT_TERMINATE_CAUSE_LOST_CARRIER 2
#define RADIUS_ACCT_TERMINATE_CAUSE_LOST_SERVICE 3
#define RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT 4
#define RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT 5
#define RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET 6
#define RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT 7
#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_ERROR 8
#define RADIUS_ACCT_TERMINATE_CAUSE_NAS_ERROR 9
#define RADIUS_ACCT_TERMINATE_CAUSE_NAS_REQUEST 10
#define RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT 11
#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_UNNEEDED 12
#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_PREEMPTED 13
#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_SUSPENDED 14
#define RADIUS_ACCT_TERMINATE_CAUSE_SERVICE_UNAVAILABLE 15
#define RADIUS_ACCT_TERMINATE_CAUSE_CALLBACK 16
#define RADIUS_ACCT_TERMINATE_CAUSE_USER_ERROR 17
#define RADIUS_ACCT_TERMINATE_CAUSE_HOST_REQUEST 18
struct radius_attr_vendor {
u8 vendor_type;
u8 vendor_length;
} __attribute__ ((packed));
#define RADIUS_VENDOR_ID_CISCO 9
#define RADIUS_CISCO_AV_PAIR 1
/* RFC 2548 - Microsoft Vendor-specific RADIUS Attributes */
#define RADIUS_VENDOR_ID_MICROSOFT 311
enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
};
struct radius_ms_mppe_keys {
u8 *send;
size_t send_len;
u8 *recv;
size_t recv_len;
};
/* RADIUS message structure for new and parsed messages */
struct radius_msg {
unsigned char *buf;
size_t buf_size; /* total size allocated for buf */
size_t buf_used; /* bytes used in buf */
struct radius_hdr *hdr;
struct radius_attr_hdr **attrs; /* array of pointers to attributes */
size_t attr_size; /* total size of the attribute pointer array */
size_t attr_used; /* total number of attributes in the array */
};
/* Default size to be allocated for new RADIUS messages */
#define RADIUS_DEFAULT_MSG_SIZE 1024
/* Default size to be allocated for attribute array */
#define RADIUS_DEFAULT_ATTR_COUNT 16
/* MAC address ASCII format for IEEE 802.1X use
* (draft-congdon-radius-8021x-20.txt) */
#define RADIUS_802_1X_ADDR_FORMAT "%02X-%02X-%02X-%02X-%02X-%02X"
/* MAC address ASCII format for non-802.1X use */
#define RADIUS_ADDR_FORMAT "%02x%02x%02x%02x%02x%02x"
struct radius_msg *radius_msg_new(u8 code, u8 identifier);
int radius_msg_initialize(struct radius_msg *msg, size_t init_len);
void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier);
void radius_msg_free(struct radius_msg *msg);
void radius_msg_dump(struct radius_msg *msg);
int radius_msg_finish(struct radius_msg *msg, u8 *secret, size_t secret_len);
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
size_t secret_len, const u8 *req_authenticator);
void radius_msg_finish_acct(struct radius_msg *msg, u8 *secret,
size_t secret_len);
struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
u8 *data, size_t data_len);
struct radius_msg *radius_msg_parse(const u8 *data, size_t len);
int radius_msg_add_eap(struct radius_msg *msg, u8 *data, size_t data_len);
u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *len);
int radius_msg_verify(struct radius_msg *msg, u8 *secret, size_t secret_len,
struct radius_msg *sent_msg);
int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret,
size_t secret_len, const u8 *req_auth);
int radius_msg_verify_acct(struct radius_msg *msg, u8 *secret,
size_t secret_len, struct radius_msg *sent_msg);
int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
u8 type);
void radius_msg_make_authenticator(struct radius_msg *msg,
u8 *data, size_t len);
struct radius_ms_mppe_keys *
radius_msg_get_ms_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
u8 *secret, size_t secret_len);
struct radius_ms_mppe_keys *
radius_msg_get_cisco_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
u8 *secret, size_t secret_len);
int radius_msg_add_mppe_keys(struct radius_msg *msg,
const u8 *req_authenticator,
const u8 *secret, size_t secret_len,
const u8 *send_key, size_t send_key_len,
const u8 *recv_key, size_t recv_key_len);
struct radius_attr_hdr *
radius_msg_add_attr_user_password(struct radius_msg *msg,
u8 *data, size_t data_len,
u8 *secret, size_t secret_len);
int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len);
static inline int radius_msg_add_attr_int32(struct radius_msg *msg, u8 type,
u32 value)
{
u32 val = htonl(value);
return radius_msg_add_attr(msg, type, (u8 *) &val, 4) != NULL;
}
static inline int radius_msg_get_attr_int32(struct radius_msg *msg, u8 type,
u32 *value)
{
u32 val;
int res;
res = radius_msg_get_attr(msg, type, (u8 *) &val, 4);
if (res != 4)
return -1;
*value = ntohl(val);
return 0;
}
int radius_msg_get_attr_ptr(struct radius_msg *msg, u8 type, u8 **buf,
size_t *len);
#endif /* RADIUS_H */

View File

@ -489,9 +489,12 @@ int tls_global_private_key(void *_ssl_ctx, const char *private_key,
if (private_key == NULL)
return 0;
passwd = strdup(private_key_passwd);
if (passwd == NULL)
return -1;
if (private_key_passwd) {
passwd = strdup(private_key_passwd);
if (passwd == NULL)
return -1;
} else
passwd = NULL;
SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);

View File

@ -1,6 +1,6 @@
#ifndef VERSION_H
#define VERSION_H
#define VERSION_STR "0.3.8"
#define VERSION_STR "0.3.9"
#endif /* VERSION_H */

View File

@ -1035,6 +1035,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
if (hostapd_get_rand(wpa_s->snonce, WPA_NONCE_LEN)) {
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to get "
"random data for SNonce");
free(rbuf);
return;
}
wpa_s->renew_snonce = 0;
@ -1100,6 +1101,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
wpa_s->cur_pmksa = NULL;
abort_cached = 1;
} else {
free(rbuf);
return;
}
}
@ -1110,6 +1112,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
"been received from the external IEEE "
"802.1X Supplicant - ignoring WPA "
"EAPOL-Key frame");
free(rbuf);
return;
#endif /* CONFIG_XSUPPLICANT_IFACE */
}
@ -1120,6 +1123,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
"full EAP authenication");
wpa_eapol_send(wpa_s, IEEE802_1X_TYPE_EAPOL_START,
(u8 *) "", 0);
free(rbuf);
return;
}
@ -1963,8 +1967,9 @@ static void wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s,
if (be_to_host16(key->key_data_length) > extra_len) {
wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
"key_data overflow (%d > %d)",
be_to_host16(key->key_data_length), extra_len);
"key_data overflow (%d > %lu)",
be_to_host16(key->key_data_length),
(unsigned long) extra_len);
return;
}
@ -2009,6 +2014,12 @@ void wpa_supplicant_rx_eapol(void *ctx, unsigned char *src_addr,
wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since "
"no key management is configured");
return;
}
if (wpa_s->eapol_received == 0) {
/* Timeout for completing IEEE 802.1X and WPA authentication */
wpa_supplicant_req_auth_timeout(
@ -2252,6 +2263,7 @@ int rsn_preauth_init(struct wpa_supplicant *wpa_s, u8 *dst)
}
memset(ctx, 0, sizeof(*ctx));
ctx->ctx = wpa_s;
ctx->msg_ctx = wpa_s;
ctx->preauth = 1;
ctx->cb = rsn_preauth_eapol_cb;
ctx->cb_ctx = wpa_s;

View File

@ -360,18 +360,19 @@ void wpa_supplicant_notify_eapol_done(void *ctx)
}
static int wpa_blacklisted(struct wpa_supplicant *wpa_s, const u8 *bssid)
static struct wpa_blacklist *
wpa_blacklist_get(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_blacklist *e;
e = wpa_s->blacklist;
while (e) {
if (memcmp(e->bssid, bssid, ETH_ALEN) == 0)
return 1;
return e;
e = e->next;
}
return 0;
return NULL;
}
@ -379,14 +380,21 @@ static int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_blacklist *e;
if (wpa_blacklisted(wpa_s, bssid))
e = wpa_blacklist_get(wpa_s, bssid);
if (e) {
e->count++;
wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count "
"incremented to %d",
MAC2STR(bssid), e->count);
return 0;
}
e = malloc(sizeof(*e));
if (e == NULL)
return -1;
memset(e, 0, sizeof(*e));
memcpy(e->bssid, bssid, ETH_ALEN);
e->count = 1;
e->next = wpa_s->blacklist;
wpa_s->blacklist = e;
wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist",
@ -1341,6 +1349,18 @@ static int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
return -1;
}
wpa_hexdump(MSG_DEBUG, "WPA: Own WPA IE", wpa_ie, *wpa_ie_len);
if (wpa_s->assoc_wpa_ie == NULL) {
/*
* Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
* the correct version of the IE even if PMKSA caching is
* aborted (which would remove PMKID from IE generation).
*/
wpa_s->assoc_wpa_ie = malloc(*wpa_ie_len);
if (wpa_s->assoc_wpa_ie) {
memcpy(wpa_s->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
wpa_s->assoc_wpa_ie_len = *wpa_ie_len;
}
}
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
wpa_s->pmk_len = PMK_LEN;
@ -1651,6 +1671,7 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
struct wpa_ssid *ssid;
struct wpa_scan_result *bss, *selected = NULL;
int i;
struct wpa_blacklist *e;
wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d",
group->priority);
@ -1666,7 +1687,8 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
wpa_ssid_txt(bss->ssid, bss->ssid_len),
(unsigned long) bss->wpa_ie_len,
(unsigned long) bss->rsn_ie_len);
if (wpa_blacklisted(wpa_s, bss->bssid)) {
if ((e = wpa_blacklist_get(wpa_s, bss->bssid)) &&
e->count > 1) {
wpa_printf(MSG_DEBUG, " skip - blacklisted");
continue;
}
@ -1733,7 +1755,8 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
* allows this. */
for (i = 0; i < num && !selected; i++) {
bss = &results[i];
if (wpa_blacklisted(wpa_s, bss->bssid)) {
if ((e = wpa_blacklist_get(wpa_s, bss->bssid)) &&
e->count > 1) {
continue;
}
for (ssid = group; ssid; ssid = ssid->pnext) {
@ -2088,7 +2111,8 @@ static void usage(void)
"usage:\n"
" wpa_supplicant [-BddehLqqvw] -i<ifname> -c<config file> "
"[-D<driver>] \\\n"
" [-N -i<ifname> -c<conf> [-D<driver>] ...]\n"
" [-P<pid file>] "
"[-N -i<ifname> -c<conf> [-D<driver>] ...]\n"
"\n"
"drivers:\n",
wpa_supplicant_version, wpa_supplicant_license);
@ -2135,6 +2159,7 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void)
if (wpa_s == NULL)
return NULL;
memset(wpa_s, 0, sizeof(*wpa_s));
wpa_s->ctrl_sock = -1;
#ifdef CONFIG_XSUPPLICANT_IFACE
wpa_s->dot1x_s = -1;
#endif /* CONFIG_XSUPPLICANT_IFACE */
@ -2279,6 +2304,7 @@ static void wpa_supplicant_deinit(struct wpa_supplicant *wpa_s)
wpa_drv_set_drop_unencrypted(wpa_s, 0);
wpa_drv_set_countermeasures(wpa_s, 0);
wpa_clear_keys(wpa_s, NULL);
wpa_drv_deinit(wpa_s);
}
@ -2291,6 +2317,7 @@ int main(int argc, char *argv[])
struct wpa_supplicant *head, *wpa_s;
int c;
const char *confname, *driver, *ifname;
char *pid_file = NULL;
int daemonize = 0, wait_for_interface = 0, disable_eapol = 0, exitcode;
#ifdef CONFIG_NATIVE_WINDOWS
@ -2312,7 +2339,7 @@ int main(int argc, char *argv[])
ifname = confname = driver = NULL;
for (;;) {
c = getopt(argc, argv, "Bc:D:dehi:KLNqtvw");
c = getopt(argc, argv, "Bc:D:dehi:KLNP:qtvw");
if (c < 0)
break;
switch (c) {
@ -2347,6 +2374,9 @@ int main(int argc, char *argv[])
case 'L':
license();
return -1;
case 'P':
pid_file = rel2abs_path(optarg);
break;
case 'q':
wpa_debug_level++;
break;
@ -2407,6 +2437,14 @@ int main(int argc, char *argv[])
}
}
if (pid_file) {
FILE *f = fopen(pid_file, "w");
if (f) {
fprintf(f, "%u\n", getpid());
fclose(f);
}
}
eloop_register_signal(SIGINT, wpa_supplicant_terminate, NULL);
eloop_register_signal(SIGTERM, wpa_supplicant_terminate, NULL);
#ifndef CONFIG_NATIVE_WINDOWS
@ -2431,6 +2469,11 @@ int main(int argc, char *argv[])
eloop_destroy();
if (pid_file) {
unlink(pid_file);
free(pid_file);
}
#ifdef CONFIG_NATIVE_WINDOWS
WSACleanup();
#endif /* CONFIG_NATIVE_WINDOWS */

View File

@ -49,6 +49,7 @@ struct wpa_ptk {
struct wpa_blacklist {
struct wpa_blacklist *next;
u8 bssid[ETH_ALEN];
int count;
};
@ -326,7 +327,7 @@ static inline int wpa_drv_set_wpa(struct wpa_supplicant *wpa_s, int enabled)
if (wpa_s->driver->set_wpa) {
return wpa_s->driver->set_wpa(wpa_s->drv_priv, enabled);
}
return -1;
return 0;
}
static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s,