#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
# 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
*/
u16 max_listen_interval;
+ int disable_pmksa_caching;
int okc; /* Opportunistic Key Caching */
int wps_state;
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;
*/
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
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,
int peerkey;
int wmm_enabled;
int wmm_uapsd;
+ int disable_pmksa_caching;
int okc;
int tx_status;
#ifdef CONFIG_IEEE80211W
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;
/*
* 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
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;
/*
* 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
unsigned int server_cert_only:1;
u8 srv_cert_hash[32];
+
+ unsigned int flags;
};
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);
return -1;
}
+ conn->flags = params->flags;
+
tls_get_errors(tls_ctx);
return 0;
int monitor_sock;
int monitor_ifidx;
+ int no_monitor_iface_capab;
int disable_11b_rates;
unsigned int pending_remain_on_chan:1;
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;
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;
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));
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;
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 */
{
struct eap_sm *sm = ctx;
char *hash_hex = NULL;
- char *cert_hex = NULL;
switch (ev) {
case TLS_CERT_CHAIN_FAILURE:
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);
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);
}
*/
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);
};
/**
#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 =
{
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
};
* @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);
};
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]);
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);
}
}
- 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;
/*
* 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
}
+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)
/*
* 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
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,
/*
* 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
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;
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);
}
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);
/*
* 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
*/
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;
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);
/*
* 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
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);
#
LOCAL_PATH := $(call my-dir)
+PKG_CONFIG ?= pkg-config
WPA_BUILD_SUPPLICANT := false
ifneq ($(TARGET_SIMULATOR),true)
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),)
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
export LIBDIR ?= /usr/local/lib/
export BINDIR ?= /usr/local/sbin/
+PKG_CONFIG ?= pkg-config
CFLAGS += -I../src
CFLAGS += -I../src/utils
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),)
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
{
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;
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 */
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;
CFLAGS = -MMD -O2 -Wall -g
endif
+PKG_CONFIG ?= pkg-config
CFLAGS += -I../../src -I../../src/utils
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
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),)
#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
/**
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
*/
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)
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 ||
END_ARGS
}
},
+ { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
+ {
+ { "path", "o", ARG_OUT },
+ END_ARGS
+ }
+ },
{ "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
{
{ "name", "s", ARG_OUT },
}
},
#endif /* CONFIG_P2P */
+ { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ { "certification", "a{sv}", ARG_OUT },
+ END_ARGS
+ }
+ },
{ NULL, NULL, { END_ARGS } }
};
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 */
{
}
+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 */
{
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];
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++) {
}
#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
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);
{
}
+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)
{
/*
* 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
#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"
}
+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)
{
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) {
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;
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);
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 */
}
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);
+}
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 */
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';
#include "wps_supplicant.h"
#include "bss.h"
#include "scan.h"
+#include "notify.h"
#ifndef CONFIG_NO_CONFIG_BLOBS
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 */
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) {