wpa_supplicant: Clear blacklist on connect
[mech_eap.git] / wpa_supplicant / wpa_supplicant.c
index 15f8569..2ba9c38 100644 (file)
@@ -456,6 +456,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
                             wpa_s, NULL);
 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
 
+       eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+
        wpas_wps_deinit(wpa_s);
 
        wpabuf_free(wpa_s->pending_eapol_rx);
@@ -729,6 +731,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
                        ssid && ssid->id_str ? ssid->id_str : "");
 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
                wpas_clear_temp_disabled(wpa_s, ssid, 1);
+               wpa_blacklist_clear(wpa_s);
                wpa_s->extra_blacklist_count = 0;
                wpa_s->new_connection = 0;
                wpa_drv_set_operstate(wpa_s, 1);
@@ -1237,7 +1240,12 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
        }
 
        if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
-               wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
+               int psk_set = 0;
+
+               if (ssid->psk_set) {
+                       wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
+                       psk_set = 1;
+               }
 #ifndef CONFIG_NO_PBKDF2
                if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
                    ssid->passphrase) {
@@ -1247,6 +1255,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                        wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
                                        psk, PMK_LEN);
                        wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
+                       psk_set = 1;
                        os_memset(psk, 0, sizeof(psk));
                }
 #endif /* CONFIG_NO_PBKDF2 */
@@ -1284,6 +1293,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                                                "external passphrase)",
                                                psk, PMK_LEN);
                                wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
+                               psk_set = 1;
                                os_memset(psk, 0, sizeof(psk));
                        } else
 #endif /* CONFIG_NO_PBKDF2 */
@@ -1296,6 +1306,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                                        return -1;
                                }
                                wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
+                               psk_set = 1;
                                os_memset(psk, 0, sizeof(psk));
                        } else {
                                wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
@@ -1309,6 +1320,12 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                        ext_password_free(pw);
                }
 #endif /* CONFIG_EXT_PASSWORD */
+
+               if (!psk_set) {
+                       wpa_msg(wpa_s, MSG_INFO,
+                               "No PSK available for association");
+                       return -1;
+               }
        } else
                wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
 
@@ -2625,6 +2642,13 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
                eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
                wpa_s->connect_without_scan =
                        (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
+
+               /*
+                * Don't optimize next scan freqs since a new ESS has been
+                * selected.
+                */
+               os_free(wpa_s->next_scan_freqs);
+               wpa_s->next_scan_freqs = NULL;
        } else {
                wpa_s->connect_without_scan = NULL;
        }
@@ -3230,7 +3254,8 @@ static int wpa_supplicant_daemon(const char *pid_file)
 }
 
 
-static struct wpa_supplicant * wpa_supplicant_alloc(void)
+static struct wpa_supplicant *
+wpa_supplicant_alloc(struct wpa_supplicant *parent)
 {
        struct wpa_supplicant *wpa_s;
 
@@ -3240,7 +3265,7 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void)
        wpa_s->scan_req = INITIAL_SCAN_REQ;
        wpa_s->scan_interval = 5;
        wpa_s->new_connection = 1;
-       wpa_s->parent = wpa_s;
+       wpa_s->parent = parent ? parent : wpa_s;
        wpa_s->sched_scanning = 0;
 
        return wpa_s;
@@ -4294,6 +4319,7 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
  * wpa_supplicant_add_iface - Add a new network interface
  * @global: Pointer to global data from wpa_supplicant_init()
  * @iface: Interface configuration options
+ * @parent: Parent interface or %NULL to assign new interface as parent
  * Returns: Pointer to the created interface or %NULL on failure
  *
  * This function is used to add new network interfaces for %wpa_supplicant.
@@ -4303,7 +4329,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
  * e.g., when a hotplug network adapter is inserted.
  */
 struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
-                                                struct wpa_interface *iface)
+                                                struct wpa_interface *iface,
+                                                struct wpa_supplicant *parent)
 {
        struct wpa_supplicant *wpa_s;
        struct wpa_interface t_iface;
@@ -4312,7 +4339,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
        if (global == NULL || iface == NULL)
                return NULL;
 
-       wpa_s = wpa_supplicant_alloc();
+       wpa_s = wpa_supplicant_alloc(parent);
        if (wpa_s == NULL)
                return NULL;
 
@@ -4955,6 +4982,15 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
                str_clear_free(eap->external_sim_resp);
                eap->external_sim_resp = os_strdup(value);
                break;
+       case WPA_CTRL_REQ_PSK_PASSPHRASE:
+               if (wpa_config_set(ssid, "psk", value, 0) < 0)
+                       return -1;
+               ssid->mem_only_psk = 1;
+               if (ssid->passphrase)
+                       wpa_config_update_psk(ssid);
+               if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
+                       wpa_supplicant_req_scan(wpa_s, 0, 0);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
                return -1;
@@ -4983,7 +5019,7 @@ int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
        if (ssid->disabled)
                return 1;
 
-       if (wpa_s && wpa_s->drv_capa_known)
+       if (wpa_s->drv_capa_known)
                drv_enc = wpa_s->drv_enc;
        else
                drv_enc = (unsigned int) -1;
@@ -5002,7 +5038,8 @@ int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
        }
 
        if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
-           (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk)
+           (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
+           !ssid->mem_only_psk)
                return 1;
 
        return 0;