diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2011-07-07 11:18:38 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2011-07-07 11:23:25 -0700 |
| commit | c55524ad84d13014e8019491c2b17e5dcf13545a (patch) | |
| tree | 3c1a0f04ed12cadca7312b1b6f3f0c0caa6018ca | |
| parent | 13970b010f3e5b274336677311a5586410ecc8fa (diff) | |
| download | android_external_wpa_supplicant_8-c55524ad84d13014e8019491c2b17e5dcf13545a.tar.gz android_external_wpa_supplicant_8-c55524ad84d13014e8019491c2b17e5dcf13545a.tar.bz2 android_external_wpa_supplicant_8-c55524ad84d13014e8019491c2b17e5dcf13545a.zip | |
Accumulative patch from commit 8fd0f0f323a922aa88ec720ee524f7105d3b0f64
Fix D-Bus build without CONFIG_P2P=y
nl80211: Allow AP mode to be started without monitor interface
nl80211: Process association/disassociation events in AP mode
DBus/P2P: Adding decl for PersistentGroupRemoved signal
DBus/P2P: Rectified type of SecondaryDeviceTypes in device property Get
P2P: Only call dev_lost() for devices that have been dev_found()
wpa_cli: Add missing parameter for P2P_GROUP_ADD command
wpa_supplicant: Respect PKG_CONFIG variable if set in the environment
TLS: Add support for tls_disable_time_checks=1 in client mode
hostapd: Clear keys configured when hostapd reloads configuration
Add dbus signal for information about server certification
Move peer certificate wpa_msg() calls to notify.c
wpa_supplicant AP: Disable AP mode on disassoc paths
wpa_s AP mode: Enable HT20 if driver supports it
Allow PMKSA caching to be disabled on Authenticator
FT: Disable PMKSA cache for FT-IEEE8021X
FT: Clear SME ft_used/ft_ies when disconnecting
8fd0f0f323a922aa88ec720ee524f7105d3b0f64
Change-Id: I6ae333196c36ffa7589662d5269fabfc3b994605
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
38 files changed, 452 insertions, 71 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 835f0500..bfd48098 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1904,6 +1904,8 @@ struct hostapd_config * hostapd_config_read(const char *fname) #endif /* CONFIG_IEEE80211N */ } else if (os_strcmp(buf, "max_listen_interval") == 0) { bss->max_listen_interval = atoi(pos); + } else if (os_strcmp(buf, "disable_pmksa_caching") == 0) { + bss->disable_pmksa_caching = atoi(pos); } else if (os_strcmp(buf, "okc") == 0) { bss->okc = atoi(pos); #ifdef CONFIG_WPS diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index e0525e40..3b1548c1 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -770,6 +770,13 @@ own_ip_addr=127.0.0.1 # dot11AssociationSAQueryRetryTimeout, 1...4294967295 #assoc_sa_query_retry_timeout=201 +# disable_pmksa_caching: Disable PMKSA caching +# This parameter can be used to disable caching of PMKSA created through EAP +# authentication. RSN preauthentication may still end up using PMKSA caching if +# it is enabled (rsn_preauth=1). +# 0 = PMKSA caching enabled (default) +# 1 = PMKSA caching disabled +#disable_pmksa_caching=0 # okc: Opportunistic Key Caching (aka Proactive Key Caching) # Allow PMK cache to be shared opportunistically among configured interfaces diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 0a3e76ec..09eed5ab 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -288,6 +288,7 @@ struct hostapd_bss_config { */ u16 max_listen_interval; + int disable_pmksa_caching; int okc; /* Opportunistic Key Caching */ int wps_state; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index d8af5713..f00a5446 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -40,6 +40,7 @@ static int hostapd_flush_old_stations(struct hostapd_data *hapd); static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd); +static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd); extern int wpa_debug_level; @@ -109,6 +110,7 @@ int hostapd_reload_config(struct hostapd_iface *iface) */ for (j = 0; j < iface->num_bss; j++) { hostapd_flush_old_stations(iface->bss[j]); + hostapd_broadcast_wep_clear(iface->bss[j]); #ifndef CONFIG_NO_RADIUS /* TODO: update dynamic data based on changed configuration diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index cfb2cada..3fbb88b9 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2727,7 +2727,8 @@ const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len) int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, int session_timeout, struct eapol_state_machine *eapol) { - if (sm == NULL || sm->wpa != WPA_VERSION_WPA2) + if (sm == NULL || sm->wpa != WPA_VERSION_WPA2 || + sm->wpa_auth->conf.disable_pmksa_caching) return -1; if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, PMK_LEN, diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index b3e1ff02..e533a140 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -143,6 +143,7 @@ struct wpa_auth_config { int peerkey; int wmm_enabled; int wmm_uapsd; + int disable_pmksa_caching; int okc; int tx_status; #ifdef CONFIG_IEEE80211W diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index b35b7ba5..0e3cb31f 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -48,6 +48,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, wconf->peerkey = conf->peerkey; wconf->wmm_enabled = conf->wmm_enabled; wconf->wmm_uapsd = conf->wmm_uapsd; + wconf->disable_pmksa_caching = conf->disable_pmksa_caching; wconf->okc = conf->okc; #ifdef CONFIG_IEEE80211W wconf->ieee80211w = conf->ieee80211w; diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c index 64124d8a..cc165f64 100644 --- a/src/crypto/tls_internal.c +++ b/src/crypto/tls_internal.c @@ -1,6 +1,6 @@ /* * TLS interface functions and an internal TLS implementation - * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -211,6 +211,9 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, return -1; } + tlsv1_client_set_time_checks( + conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS)); + return 0; #else /* CONFIG_TLS_INTERNAL_CLIENT */ return -1; diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index bf92a113..14ff87e2 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -1,6 +1,6 @@ /* * SSL/TLS interface functions for OpenSSL - * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -86,6 +86,8 @@ struct tls_connection { unsigned int server_cert_only:1; u8 srv_cert_hash[32]; + + unsigned int flags; }; @@ -1192,6 +1194,13 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) preverify_ok = 1; if (!preverify_ok && depth > 0 && conn->server_cert_only) preverify_ok = 1; + if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) && + (err == X509_V_ERR_CERT_HAS_EXPIRED || + err == X509_V_ERR_CERT_NOT_YET_VALID)) { + wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity " + "time mismatch"); + preverify_ok = 1; + } err_str = X509_verify_cert_error_string(err); @@ -2730,6 +2739,8 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, return -1; } + conn->flags = params->flags; + tls_get_errors(tls_ctx); return 0; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index cfc93725..50eac8ae 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -157,6 +157,7 @@ struct wpa_driver_nl80211_data { int monitor_sock; int monitor_ifidx; + int no_monitor_iface_capab; int disable_11b_rates; unsigned int pending_remain_on_chan:1; @@ -1325,6 +1326,20 @@ static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv, return; addr = nla_data(tb[NL80211_ATTR_MAC]); wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr)); + + if (drv->nlmode == NL80211_IFTYPE_AP && + drv->no_monitor_iface_capab) { + u8 *ies = NULL; + size_t ies_len = 0; + if (tb[NL80211_ATTR_IE]) { + ies = nla_data(tb[NL80211_ATTR_IE]); + ies_len = nla_len(tb[NL80211_ATTR_IE]); + } + wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len); + drv_event_assoc(drv->ctx, addr, ies, ies_len, 0); + return; + } + if (drv->nlmode != NL80211_IFTYPE_ADHOC) return; @@ -1345,6 +1360,13 @@ static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv, addr = nla_data(tb[NL80211_ATTR_MAC]); wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR, MAC2STR(addr)); + + if (drv->nlmode == NL80211_IFTYPE_AP && + drv->no_monitor_iface_capab) { + drv_event_disassoc(drv->ctx, addr); + return; + } + if (drv->nlmode != NL80211_IFTYPE_ADHOC) return; @@ -3635,6 +3657,12 @@ static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv, if (encrypt) rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP; + if (drv->monitor_sock < 0) { + wpa_printf(MSG_DEBUG, "nl80211: No monitor socket available " + "for %s", __func__); + return -1; + } + res = sendmsg(drv->monitor_sock, &msg, 0); if (res < 0) { wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno)); @@ -4273,6 +4301,12 @@ nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv) nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL, 0); + if (drv->monitor_ifidx == -EOPNOTSUPP) { + wpa_printf(MSG_DEBUG, "nl80211: Driver does not support " + "monitor interface type - try to run without it"); + drv->no_monitor_iface_capab = 1; + } + if (drv->monitor_ifidx < 0) return -1; @@ -4971,8 +5005,9 @@ static int wpa_driver_nl80211_set_mode(void *priv, int mode) done: if (!ret && nlmode == NL80211_IFTYPE_AP) { /* Setup additional AP mode functionality if needed */ - if (drv->monitor_ifidx < 0 && - nl80211_create_monitor_interface(drv)) + if (!drv->no_monitor_iface_capab && drv->monitor_ifidx < 0 && + nl80211_create_monitor_interface(drv) && + !drv->no_monitor_iface_capab) return -1; } else if (!ret && nlmode != NL80211_IFTYPE_AP) { /* Remove additional AP mode functionality */ diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 8a9826f1..ecfaf309 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -1168,7 +1168,6 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, { struct eap_sm *sm = ctx; char *hash_hex = NULL; - char *cert_hex = NULL; switch (ev) { case TLS_CERT_CHAIN_FAILURE: @@ -1180,6 +1179,9 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, data->cert_fail.reason_txt); break; case TLS_PEER_CERTIFICATE: + if (!sm->eapol_cb->notify_cert) + break; + if (data->peer_cert.hash) { size_t len = data->peer_cert.hash_len * 2 + 1; hash_hex = os_malloc(len); @@ -1189,31 +1191,15 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, data->peer_cert.hash_len); } } - wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PEER_CERT - "depth=%d subject='%s'%s%s", - data->peer_cert.depth, data->peer_cert.subject, - hash_hex ? " hash=" : "", hash_hex ? hash_hex : ""); - - if (data->peer_cert.cert) { - size_t len = wpabuf_len(data->peer_cert.cert) * 2 + 1; - cert_hex = os_malloc(len); - if (cert_hex == NULL) - break; - wpa_snprintf_hex(cert_hex, len, - wpabuf_head(data->peer_cert.cert), - wpabuf_len(data->peer_cert.cert)); - wpa_msg_ctrl(sm->msg_ctx, MSG_INFO, - WPA_EVENT_EAP_PEER_CERT - "depth=%d subject='%s' cert=%s", - data->peer_cert.depth, - data->peer_cert.subject, - cert_hex); - } + + sm->eapol_cb->notify_cert(sm->eapol_ctx, + data->peer_cert.depth, + data->peer_cert.subject, + hash_hex, data->peer_cert.cert); break; } os_free(hash_hex); - os_free(cert_hex); } diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h index 35509090..2a80d4e7 100644 --- a/src/eap_peer/eap.h +++ b/src/eap_peer/eap.h @@ -221,6 +221,17 @@ struct eapol_callbacks { */ void (*eap_param_needed)(void *ctx, const char *field, const char *txt); + + /** + * notify_cert - Notification of a peer certificate + * @ctx: eapol_ctx from eap_peer_sm_init() call + * @depth: Depth in certificate chain (0 = server) + * @subject: Subject of the peer certificate + * @cert_hash: SHA-256 hash of the certificate + * @cert: Peer certificate + */ + void (*notify_cert)(void *ctx, int depth, const char *subject, + const char *cert_hash, const struct wpabuf *cert); }; /** diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index 18abb4e3..bb6cff60 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -1825,6 +1825,15 @@ static void eapol_sm_eap_param_needed(void *ctx, const char *field, #define eapol_sm_eap_param_needed NULL #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ +static void eapol_sm_notify_cert(void *ctx, int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ + struct eapol_sm *sm = ctx; + if (sm->ctx->cert_cb) + sm->ctx->cert_cb(sm->ctx->ctx, depth, subject, + cert_hash, cert); +} static struct eapol_callbacks eapol_cb = { @@ -1837,7 +1846,8 @@ static struct eapol_callbacks eapol_cb = eapol_sm_set_config_blob, eapol_sm_get_config_blob, eapol_sm_notify_pending, - eapol_sm_eap_param_needed + eapol_sm_eap_param_needed, + eapol_sm_notify_cert }; diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h index 1bdf8cdd..3ea7e799 100644 --- a/src/eapol_supp/eapol_supp_sm.h +++ b/src/eapol_supp/eapol_supp_sm.h @@ -220,6 +220,17 @@ struct eapol_ctx { * @authorized: Whether the supplicant port is now in authorized state */ void (*port_cb)(void *ctx, int authorized); + + /** + * cert_cb - Notification of a peer certificate + * @ctx: Callback context (ctx) + * @depth: Depth in certificate chain (0 = server) + * @subject: Subject of the peer certificate + * @cert_hash: SHA-256 hash of the certificate + * @cert: Peer certificate + */ + void (*cert_cb)(void *ctx, int depth, const char *subject, + const char *cert_hash, const struct wpabuf *cert); }; diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 191099a5..d4fac561 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -634,7 +634,10 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) if (p2p->pending_client_disc_go == dev) p2p->pending_client_disc_go = NULL; - p2p->cfg->dev_lost(p2p->cfg->cb_ctx, dev->info.p2p_device_addr); + /* dev_lost() device, but only if it was previously dev_found() */ + if (dev->flags & P2P_DEV_REPORTED_ONCE) + p2p->cfg->dev_lost(p2p->cfg->cb_ctx, + dev->info.p2p_device_addr); for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { wpabuf_free(dev->info.wps_vendor_ext[i]); diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 01a46dc9..7c0ac873 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -198,7 +198,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state " "machines", sm->pmk, pmk_len); sm->pmk_len = pmk_len; - if (sm->proto == WPA_PROTO_RSN) { + if (sm->proto == WPA_PROTO_RSN && + !wpa_key_mgmt_ft(sm->key_mgmt)) { pmksa_cache_add(sm->pmksa, sm->pmk, pmk_len, src_addr, sm->own_addr, sm->network_ctx, sm->key_mgmt); @@ -227,7 +228,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, } } - if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) { + if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && + !wpa_key_mgmt_ft(sm->key_mgmt)) { /* Send EAPOL-Start to trigger full EAP authentication. */ u8 *buf; size_t buflen; diff --git a/src/tls/tlsv1_client.c b/src/tls/tlsv1_client.c index afb60317..8b7e26f2 100644 --- a/src/tls/tlsv1_client.c +++ b/src/tls/tlsv1_client.c @@ -1,6 +1,6 @@ /* * TLSv1 client (RFC 2246) - * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -656,6 +656,12 @@ int tlsv1_client_set_cred(struct tlsv1_client *conn, } +void tlsv1_client_set_time_checks(struct tlsv1_client *conn, int enabled) +{ + conn->disable_time_checks = !enabled; +} + + void tlsv1_client_set_session_ticket_cb(struct tlsv1_client *conn, tlsv1_client_session_ticket_cb cb, void *ctx) diff --git a/src/tls/tlsv1_client.h b/src/tls/tlsv1_client.h index 16ad57d4..a620d62e 100644 --- a/src/tls/tlsv1_client.h +++ b/src/tls/tlsv1_client.h @@ -1,6 +1,6 @@ /* * TLSv1 client (RFC 2246) - * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -47,6 +47,7 @@ int tlsv1_client_get_keyblock_size(struct tlsv1_client *conn); int tlsv1_client_set_cipher_list(struct tlsv1_client *conn, u8 *ciphers); int tlsv1_client_set_cred(struct tlsv1_client *conn, struct tlsv1_credentials *cred); +void tlsv1_client_set_time_checks(struct tlsv1_client *conn, int enabled); typedef int (*tlsv1_client_session_ticket_cb) (void *ctx, const u8 *ticket, size_t len, const u8 *client_random, diff --git a/src/tls/tlsv1_client_i.h b/src/tls/tlsv1_client_i.h index 7fe179f1..f091bcf0 100644 --- a/src/tls/tlsv1_client_i.h +++ b/src/tls/tlsv1_client_i.h @@ -1,6 +1,6 @@ /* * TLSv1 client - internal structures - * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -39,6 +39,7 @@ struct tlsv1_client { unsigned int session_resumed:1; unsigned int session_ticket_included:1; unsigned int use_session_ticket:1; + unsigned int disable_time_checks:1; struct crypto_public_key *server_rsa_key; diff --git a/src/tls/tlsv1_client_read.c b/src/tls/tlsv1_client_read.c index ed3f2606..faa891aa 100644 --- a/src/tls/tlsv1_client_read.c +++ b/src/tls/tlsv1_client_read.c @@ -365,7 +365,8 @@ static int tls_process_certificate(struct tlsv1_client *conn, u8 ct, if (conn->cred && x509_certificate_chain_validate(conn->cred->trusted_certs, chain, - &reason) < 0) { + &reason, conn->disable_time_checks) + < 0) { int tls_reason; wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain " "validation failed (reason=%d)", reason); diff --git a/src/tls/tlsv1_server_read.c b/src/tls/tlsv1_server_read.c index 49e811ff..fd744365 100644 --- a/src/tls/tlsv1_server_read.c +++ b/src/tls/tlsv1_server_read.c @@ -424,7 +424,7 @@ static int tls_process_certificate(struct tlsv1_server *conn, u8 ct, } if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain, - &reason) < 0) { + &reason, 0) < 0) { int tls_reason; wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain " "validation failed (reason=%d)", reason); diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index bc93df68..347f9759 100644 --- a/src/tls/x509v3.c +++ b/src/tls/x509v3.c @@ -1,6 +1,6 @@ /* * X.509v3 certificate parsing and processing (RFC 3280 profile) - * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -1834,7 +1834,7 @@ static int x509_valid_issuer(const struct x509_certificate *cert) */ int x509_certificate_chain_validate(struct x509_certificate *trusted, struct x509_certificate *chain, - int *reason) + int *reason, int disable_time_checks) { long unsigned idx; int chain_trusted = 0; @@ -1854,10 +1854,11 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted, if (chain_trusted) continue; - if ((unsigned long) now.sec < - (unsigned long) cert->not_before || - (unsigned long) now.sec > - (unsigned long) cert->not_after) { + if (!disable_time_checks && + ((unsigned long) now.sec < + (unsigned long) cert->not_before || + (unsigned long) now.sec > + (unsigned long) cert->not_after)) { wpa_printf(MSG_INFO, "X509: Certificate not valid " "(now=%lu not_before=%lu not_after=%lu)", now.sec, cert->not_before, cert->not_after); diff --git a/src/tls/x509v3.h b/src/tls/x509v3.h index 37292d7e..3e2005b9 100644 --- a/src/tls/x509v3.h +++ b/src/tls/x509v3.h @@ -1,6 +1,6 @@ /* * X.509v3 certificate parsing and processing - * Copyright (c) 2006, Jouni Malinen <j@w1.fi> + * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -120,7 +120,7 @@ int x509_certificate_check_signature(struct x509_certificate *issuer, struct x509_certificate *cert); int x509_certificate_chain_validate(struct x509_certificate *trusted, struct x509_certificate *chain, - int *reason); + int *reason, int disable_time_checks); struct x509_certificate * x509_certificate_get_subject(struct x509_certificate *chain, struct x509_name *name); diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index 6cbfe8e3..77a7c177 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -16,6 +16,7 @@ # LOCAL_PATH := $(call my-dir) +PKG_CONFIG ?= pkg-config WPA_BUILD_SUPPLICANT := false ifneq ($(TARGET_SIMULATOR),true) @@ -1147,12 +1148,12 @@ DBUS_OBJS += dbus/dbus_old_handlers_wps.c endif DBUS_OBJS += dbus/dbus_dict_helpers.c ifndef DBUS_LIBS -DBUS_LIBS := $(shell pkg-config --libs dbus-1) +DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1) endif ifndef DBUS_INCLUDE -DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) +DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1) endif -dbus_version=$(subst ., ,$(shell pkg-config --modversion dbus-1)) +dbus_version=$(subst ., ,$(shell $(PKG_CONFIG) --modversion dbus-1)) DBUS_VERSION_MAJOR=$(word 1,$(dbus_version)) DBUS_VERSION_MINOR=$(word 2,$(dbus_version)) ifeq ($(DBUS_VERSION_MAJOR),) @@ -1179,10 +1180,10 @@ ifdef CONFIG_P2P DBUS_OBJS += dbus/dbus_new_handlers_p2p.c endif ifndef DBUS_LIBS -DBUS_LIBS := $(shell pkg-config --libs dbus-1) +DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1) endif ifndef DBUS_INCLUDE -DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) +DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1) endif ifdef CONFIG_CTRL_IFACE_DBUS_INTRO DBUS_OBJS += dbus/dbus_new_introspect.c diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 767e9959..3536084c 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -8,6 +8,7 @@ endif export LIBDIR ?= /usr/local/lib/ export BINDIR ?= /usr/local/sbin/ +PKG_CONFIG ?= pkg-config CFLAGS += -I../src CFLAGS += -I../src/utils @@ -1118,12 +1119,12 @@ DBUS_OBJS += dbus/dbus_old_handlers_wps.o endif DBUS_OBJS += dbus/dbus_dict_helpers.o ifndef DBUS_LIBS -DBUS_LIBS := $(shell pkg-config --libs dbus-1) +DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1) endif ifndef DBUS_INCLUDE -DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) +DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1) endif -dbus_version=$(subst ., ,$(shell pkg-config --modversion dbus-1)) +dbus_version=$(subst ., ,$(shell $(PKG_CONFIG) --modversion dbus-1)) DBUS_VERSION_MAJOR=$(word 1,$(dbus_version)) DBUS_VERSION_MINOR=$(word 2,$(dbus_version)) ifeq ($(DBUS_VERSION_MAJOR),) @@ -1150,10 +1151,10 @@ ifdef CONFIG_P2P DBUS_OBJS += dbus/dbus_new_handlers_p2p.o endif ifndef DBUS_LIBS -DBUS_LIBS := $(shell pkg-config --libs dbus-1) +DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1) endif ifndef DBUS_INCLUDE -DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) +DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1) endif ifdef CONFIG_CTRL_IFACE_DBUS_INTRO DBUS_OBJS += dbus/dbus_new_introspect.o diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index dddac446..41dbe233 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -56,6 +56,10 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, { struct hostapd_bss_config *bss = &conf->bss[0]; int pairwise; +#ifdef CONFIG_IEEE80211N + struct hostapd_hw_modes *modes; + u16 num_modes, flags; +#endif /* CONFIG_IEEE80211N */ conf->driver = wpa_s->driver; @@ -78,9 +82,32 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, return -1; } - /* TODO: enable HT if driver supports it; + /* TODO: enable HT40 if driver supports it; * drop to 11b if driver does not support 11g */ +#ifdef CONFIG_IEEE80211N + /* + * Enable HT20 if the driver supports it, by setting conf->ieee80211n. + * Using default config settings for: conf->ht_op_mode_fixed, + * conf->ht_capab, conf->secondary_channel, conf->require_ht + */ + modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags); + if (modes) { + struct hostapd_hw_modes *mode = NULL; + int i; + for (i = 0; i < num_modes; i++) { + if (modes[i].mode == conf->hw_mode) { + mode = &modes[i]; + break; + } + } + if (mode && mode->ht_capab) + conf->ieee80211n = 1; + ieee80211_sta_free_hw_features(modes, num_modes); + modes = NULL; + } +#endif /* CONFIG_IEEE80211N */ + #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) { /* Remove 802.11b rates from supported and basic rate sets */ @@ -475,6 +502,7 @@ void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s) wpa_s->current_ssid = NULL; wpa_s->assoc_freq = 0; + wpa_s->reassociated_connection = 0; #ifdef CONFIG_P2P if (wpa_s->ap_iface->bss) wpa_s->ap_iface->bss[0]->p2p_group = NULL; diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile index cfaf58d3..a0882002 100644 --- a/wpa_supplicant/dbus/Makefile +++ b/wpa_supplicant/dbus/Makefile @@ -15,6 +15,7 @@ ifndef CFLAGS CFLAGS = -MMD -O2 -Wall -g endif +PKG_CONFIG ?= pkg-config CFLAGS += -I../../src -I../../src/utils @@ -38,10 +39,10 @@ CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW CFLAGS += -DCONFIG_CTRL_IFACE_DBUS ifndef DBUS_LIBS -DBUS_LIBS := $(shell pkg-config --libs dbus-1) +DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1) endif ifndef DBUS_INCLUDE -DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1) +DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1) endif ifdef CONFIG_CTRL_IFACE_DBUS_INTRO CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO @@ -49,7 +50,7 @@ DBUS_INCLUDE += $(shell xml2-config --cflags) DBUS_LIBS += $(shell xml2-config --libs) endif -dbus_version=$(subst ., ,$(shell pkg-config --modversion dbus-1)) +dbus_version=$(subst ., ,$(shell $(PKG_CONFIG) --modversion dbus-1)) DBUS_VERSION_MAJOR=$(word 1,$(dbus_version)) DBUS_VERSION_MINOR=$(word 2,$(dbus_version)) ifeq ($(DBUS_VERSION_MAJOR),) diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index c75fbdfa..533cb321 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -653,6 +653,54 @@ nomem: #endif /* CONFIG_WPS */ +void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s, + int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "Certification"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &iter); + if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) + goto nomem; + + if (!wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) || + !wpa_dbus_dict_append_string(&dict_iter, "subject", subject)) + goto nomem; + + if (cert_hash && + !wpa_dbus_dict_append_string(&dict_iter, "cert_hash", cert_hash)) + goto nomem; + + if (cert && + !wpa_dbus_dict_append_byte_array(&dict_iter, "cert", + wpabuf_head(cert), + wpabuf_len(cert))) + goto nomem; + + if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) + goto nomem; + + dbus_connection_send(iface->con, msg, NULL); + +nomem: + dbus_message_unref(msg); +} + #ifdef CONFIG_P2P /** @@ -1794,6 +1842,7 @@ int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, struct network_handler_args *arg; char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; +#ifdef CONFIG_P2P /* * If it is a persistent group register it as such. * This is to handle cases where an interface is being initialized @@ -1801,6 +1850,7 @@ int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, */ if (network_is_persistent_group(ssid)) return wpas_dbus_register_persistent_group(wpa_s, ssid); +#endif /* CONFIG_P2P */ /* Do nothing if the control interface is not turned on */ if (wpa_s == NULL || wpa_s->global == NULL) @@ -1868,9 +1918,11 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) ssid = wpa_config_get_network(wpa_s->conf, nid); +#ifdef CONFIG_P2P /* If it is a persistent group unregister it as such */ if (ssid && network_is_persistent_group(ssid)) return wpas_dbus_unregister_persistent_group(wpa_s, nid); +#endif /* CONFIG_P2P */ /* Do nothing if the control interface is not turned on */ if (wpa_s == NULL || wpa_s->global == NULL || @@ -2629,6 +2681,12 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, + { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE, + { + { "path", "o", ARG_OUT }, + END_ARGS + } + }, { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE, { { "name", "s", ARG_OUT }, @@ -2637,6 +2695,12 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { } }, #endif /* CONFIG_P2P */ + { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "certification", "a{sv}", ARG_OUT }, + END_ARGS + } + }, { NULL, NULL, { END_ARGS } } }; diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index 3b0d50c4..080000c0 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -201,6 +201,10 @@ void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s, const u8 *member); void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s, struct wps_event_fail *fail); +void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s, + int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert); #else /* CONFIG_CTRL_IFACE_DBUS_NEW */ @@ -443,6 +447,14 @@ wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s, { } +static inline void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s, + int depth, + const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ +} + #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ #endif /* CTRL_IFACE_DBUS_H_NEW */ diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 3fec3083..55482b47 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -660,8 +660,9 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message, { DBusMessage *reply = NULL; DBusMessageIter iter, variant_iter, dict_iter; + DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val, + iter_secdev_dict_array; const char *dev_name; - int num_sec_dev_types = 0; int num_vendor_extensions = 0; int i; const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT]; @@ -694,17 +695,28 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message, goto err_no_mem; /* Secondary device types */ - for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++) { - if (wpa_s->conf->sec_device_type[i] == NULL) - break; - num_sec_dev_types++; - } + if (wpa_s->conf->num_sec_device_types) { + if (!wpa_dbus_dict_begin_array(&dict_iter, + "SecondaryDeviceTypes", + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_BYTE_AS_STRING, + &iter_secdev_dict_entry, + &iter_secdev_dict_val, + &iter_secdev_dict_array)) + goto err_no_mem; - if (!wpa_dbus_dict_append_string_array( - &dict_iter, "SecondaryDeviceTypes", - (const char **)wpa_s->conf->sec_device_type, - num_sec_dev_types)) - goto err_no_mem; + for (i = 0; i < wpa_s->conf->num_sec_device_types; i++) + wpa_dbus_dict_bin_array_add_element( + &iter_secdev_dict_array, + wpa_s->conf->sec_device_type[i], + WPS_DEV_TYPE_LEN); + + if (!wpa_dbus_dict_end_array(&dict_iter, + &iter_secdev_dict_entry, + &iter_secdev_dict_val, + &iter_secdev_dict_array)) + goto err_no_mem; + } /* Vendor Extensions */ for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c index 6a00f3e5..d255e142 100644 --- a/wpa_supplicant/dbus/dbus_old.c +++ b/wpa_supplicant/dbus/dbus_old.c @@ -549,6 +549,59 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_WPS */ +void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s, + int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ + struct wpas_dbus_priv *iface; + DBusMessage *_signal = NULL; + const char *hash; + const char *cert_hex; + int cert_hex_len; + + /* Do nothing if the control interface is not turned on */ + if (wpa_s->global == NULL) + return; + iface = wpa_s->global->dbus; + if (iface == NULL) + return; + + _signal = dbus_message_new_signal(wpa_s->dbus_path, + WPAS_DBUS_IFACE_INTERFACE, + "Certification"); + if (_signal == NULL) { + wpa_printf(MSG_ERROR, + "dbus: wpa_supplicant_dbus_notify_certification: " + "Could not create dbus signal; likely out of " + "memory"); + return; + } + + hash = cert_hash ? cert_hash : ""; + cert_hex = cert ? wpabuf_head(cert) : ""; + cert_hex_len = cert ? wpabuf_len(cert) : 0; + + if (!dbus_message_append_args(_signal, + DBUS_TYPE_INT32,&depth, + DBUS_TYPE_STRING, &subject, + DBUS_TYPE_STRING, &hash, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &cert_hex, cert_hex_len, + DBUS_TYPE_INVALID)) { + wpa_printf(MSG_ERROR, + "dbus: wpa_supplicant_dbus_notify_certification: " + "Not enough memory to construct signal"); + goto out; + } + + dbus_connection_send(iface->con, _signal, NULL); + +out: + dbus_message_unref(_signal); + +} + /** * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface diff --git a/wpa_supplicant/dbus/dbus_old.h b/wpa_supplicant/dbus/dbus_old.h index a9840c25..95238674 100644 --- a/wpa_supplicant/dbus/dbus_old.h +++ b/wpa_supplicant/dbus/dbus_old.h @@ -82,6 +82,10 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, enum wpa_states old_state); void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); +void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s, + int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert); char * wpas_dbus_decompose_object_path(const char *path, char **network, char **bssid); @@ -114,6 +118,14 @@ wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, { } +static inline void +wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s, + int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ +} + static inline int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s) { diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c index 42a7c701..332a044a 100644 --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - test code - * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -29,6 +29,7 @@ #include "wpa_supplicant_i.h" #include "radius/radius.h" #include "radius/radius_client.h" +#include "common/wpa_ctrl.h" #include "ctrl_iface.h" #include "pcsc_funcs.h" @@ -383,6 +384,35 @@ static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx) } +static void eapol_test_cert_cb(void *ctx, int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ + struct eapol_test_data *e = ctx; + + wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT + "depth=%d subject='%s'%s%s", + depth, subject, + cert_hash ? " hash=" : "", + cert_hash ? cert_hash : ""); + + if (cert) { + char *cert_hex; + size_t len = wpabuf_len(cert) * 2 + 1; + cert_hex = os_malloc(len); + if (cert_hex) { + wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), + wpabuf_len(cert)); + wpa_msg_ctrl(e->wpa_s, MSG_INFO, + WPA_EVENT_EAP_PEER_CERT + "depth=%d subject='%s' cert=%s", + depth, subject, cert_hex); + os_free(cert_hex); + } + } +} + + static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { @@ -408,6 +438,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; + ctx->cert_cb = eapol_test_cert_cb; wpa_s->eapol = eapol_sm_init(ctx); if (wpa_s->eapol == NULL) { diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index eb6c9643..8bccb6b6 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -118,6 +118,10 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) wpa_s->ibss_rsn = NULL; #endif /* CONFIG_IBSS_RSN */ +#ifdef CONFIG_AP + wpa_supplicant_ap_deinit(wpa_s); +#endif /* CONFIG_AP */ + if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) return; @@ -128,6 +132,13 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); wpa_s->current_bss = NULL; wpa_s->assoc_freq = 0; +#ifdef CONFIG_IEEE80211R +#ifdef CONFIG_SME + if (wpa_s->sme.ft_ies) + sme_update_ft_ies(wpa_s, NULL, NULL, 0); +#endif /* CONFIG_SME */ +#endif /* CONFIG_IEEE80211R */ + if (bssid_changed) wpas_notify_bssid_changed(wpa_s); diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 6595fec9..0d2f5425 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -220,14 +220,18 @@ void wpas_notify_network_added(struct wpa_supplicant *wpa_s, void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { +#ifdef CONFIG_P2P wpas_dbus_register_persistent_group(wpa_s, ssid); +#endif /* CONFIG_P2P */ } void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { +#ifdef CONFIG_P2P wpas_dbus_unregister_persistent_group(wpa_s, ssid->id); +#endif /* CONFIG_P2P */ } @@ -551,3 +555,36 @@ void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s, else wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr); } + + +void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth, + const char *subject, const char *cert_hash, + const struct wpabuf *cert) +{ + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT + "depth=%d subject='%s'%s%s", + depth, subject, + cert_hash ? " hash=" : "", + cert_hash ? cert_hash : ""); + + if (cert) { + char *cert_hex; + size_t len = wpabuf_len(cert) * 2 + 1; + cert_hex = os_malloc(len); + if (cert_hex) { + wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), + wpabuf_len(cert)); + wpa_msg_ctrl(wpa_s, MSG_INFO, + WPA_EVENT_EAP_PEER_CERT + "depth=%d subject='%s' cert=%s", + depth, subject, cert_hex); + os_free(cert_hex); + } + } + + /* notify the old DBus API */ + wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject, + cert_hash, cert); + /* notify the new DBus API */ + wpas_dbus_signal_certification(wpa_s, depth, subject, cert_hash, cert); +} diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h index 766668fc..98cbcb1b 100644 --- a/wpa_supplicant/notify.h +++ b/wpa_supplicant/notify.h @@ -119,4 +119,8 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s, void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s, struct wps_event_fail *fail); +void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth, + const char *subject, const char *cert_hash, + const struct wpabuf *cert); + #endif /* NOTIFY_H */ diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 7453a546..3b7f215f 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1838,7 +1838,12 @@ static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, if (argc == 0) return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD"); - res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", argv[0]); + if (argc > 1) + res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s", + argv[0], argv[1]); + else + res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s", + argv[0]); if (res < 0 || (size_t) res >= sizeof(cmd)) return -1; cmd[sizeof(cmd) - 1] = '\0'; diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 2662eec4..edb94752 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -32,6 +32,7 @@ #include "wps_supplicant.h" #include "bss.h" #include "scan.h" +#include "notify.h" #ifndef CONFIG_NO_CONFIG_BLOBS @@ -611,6 +612,16 @@ static void wpa_supplicant_port_cb(void *ctx, int authorized) authorized ? "Authorized" : "Unauthorized"); wpa_drv_set_supp_port(wpa_s, authorized); } + + +static void wpa_supplicant_cert_cb(void *ctx, int depth, const char *subject, + const char *cert_hash, + const struct wpabuf *cert) +{ + struct wpa_supplicant *wpa_s = ctx; + + wpas_notify_certification(wpa_s, depth, subject, cert_hash, cert); +} #endif /* IEEE8021X_EAPOL */ @@ -641,6 +652,7 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s) ctx->eap_param_needed = wpa_supplicant_eap_param_needed; ctx->port_cb = wpa_supplicant_port_cb; ctx->cb = wpa_supplicant_eapol_cb; + ctx->cert_cb = wpa_supplicant_cert_cb; ctx->cb_ctx = wpa_s; wpa_s->eapol = eapol_sm_init(ctx); if (wpa_s->eapol == NULL) { |
