wpa_supplicant.c
来自「WPA在Linux下实现的原代码 WPA在Linux下实现的原代码」· C语言 代码 · 共 2,260 行 · 第 1/5 页
C
2,260 行
wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) ? 70 : 10, 0); } wpa_s->eapol_received++; if (wpa_s->countermeasures) { wpa_printf(MSG_INFO, "WPA: Countermeasures - dropped EAPOL " "packet"); return; } /* Source address of the incoming EAPOL frame could be compared to the * current BSSID. However, it is possible that a centralized * Authenticator could be using another MAC address than the BSSID of * an AP, so just allow any address to be used for now. The replies are * still sent to the current BSSID (if available), though. */ memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN); if (wpa_s->key_mgmt != WPA_KEY_MGMT_PSK && eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0) return; wpa_drv_poll(wpa_s); wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);}/** * wpa_supplicant_driver_init - Initialize driver interface parameters * @wpa_s: Pointer to wpa_supplicant data * @wait_for_interface: 0 = do not wait for the interface (reports a failure if * the interface is not present), 1 = wait until the interface is available * Returns: 0 on success, -1 on failure * * This function is called to initialize driver interface parameters. * wpa_drv_init() must have been called before this function to initialize the * driver interface. */int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s, int wait_for_interface){ static int interface_count = 0; for (;;) { if (wpa_s->driver->send_eapol) { const u8 *addr = wpa_drv_get_mac_addr(wpa_s); if (addr) memcpy(wpa_s->own_addr, addr, ETH_ALEN); break; } wpa_s->l2 = l2_packet_init(wpa_s->ifname, wpa_drv_get_mac_addr(wpa_s), ETH_P_EAPOL, wpa_supplicant_rx_eapol, wpa_s, 0); if (wpa_s->l2) break; else if (!wait_for_interface) return -1; printf("Waiting for interface..\n"); sleep(5); } if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) { fprintf(stderr, "Failed to get own L2 address\n"); return -1; } wpa_printf(MSG_DEBUG, "Own MAC address: " MACSTR, MAC2STR(wpa_s->own_addr)); /* Backwards compatibility call to set_wpa() handler. This is called * only just after init and just before deinit, so these handler can be * used to implement same functionality. */ if (wpa_drv_set_wpa(wpa_s, 1) < 0) { struct wpa_driver_capa capa; if (wpa_drv_get_capa(wpa_s, &capa) < 0 || !(capa.flags & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2))) { wpa_printf(MSG_DEBUG, "Driver does not support WPA."); /* Continue to allow non-WPA modes to be used. */ } else { fprintf(stderr, "Failed to enable WPA in the " "driver.\n"); return -1; } } wpa_clear_keys(wpa_s, NULL); /* Make sure that TKIP countermeasures are not left enabled (could * happen if wpa_supplicant is killed during countermeasures. */ wpa_drv_set_countermeasures(wpa_s, 0); wpa_drv_set_drop_unencrypted(wpa_s, 1); wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; wpa_supplicant_req_scan(wpa_s, interface_count, 100000); interface_count++; return 0;}static int wpa_supplicant_daemon(const char *pid_file){ wpa_printf(MSG_DEBUG, "Daemonize.."); if (daemon(0, 0)) { perror("daemon"); return -1; } if (pid_file) { FILE *f = fopen(pid_file, "w"); if (f) { fprintf(f, "%u\n", getpid()); fclose(f); } } return 0;}static struct wpa_supplicant * wpa_supplicant_alloc(void){ struct wpa_supplicant *wpa_s; wpa_s = malloc(sizeof(*wpa_s)); if (wpa_s == NULL) return NULL; memset(wpa_s, 0, sizeof(*wpa_s)); wpa_s->ctrl_sock = -1; wpa_s->scan_req = 1; return wpa_s;}static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, struct wpa_interface *iface){ wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver " "'%s' ctrl_interface '%s'", iface->ifname, iface->confname ? iface->confname : "N/A", iface->driver ? iface->driver : "default", iface->ctrl_interface ? iface->ctrl_interface : "N/A"); if (wpa_supplicant_set_driver(wpa_s, iface->driver) < 0) { return -1; } if (iface->confname) {#ifdef CONFIG_BACKEND_FILE wpa_s->confname = rel2abs_path(iface->confname); if (wpa_s->confname == NULL) { wpa_printf(MSG_ERROR, "Failed to get absolute path " "for configuration file '%s'.", iface->confname); return -1; } wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'", iface->confname, wpa_s->confname);#else /* CONFIG_BACKEND_FILE */ wpa_s->confname = strdup(iface->confname);#endif /* CONFIG_BACKEND_FILE */ wpa_s->conf = wpa_config_read(wpa_s->confname); if (wpa_s->conf == NULL) { printf("Failed to read read or parse configuration " "'%s'.\n", wpa_s->confname); return -1; } /* * Override ctrl_interface and driver_param if set on command * line. */ if (iface->ctrl_interface) { free(wpa_s->conf->ctrl_interface); wpa_s->conf->ctrl_interface = strdup(iface->ctrl_interface); } if (iface->driver_param) { free(wpa_s->conf->driver_param); wpa_s->conf->driver_param = strdup(iface->driver_param); } } else wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface, iface->driver_param); if (wpa_s->conf == NULL) { printf("\nNo configuration found.\n"); return -1; } if (iface->ifname == NULL) { printf("\nInterface name is required.\n"); return -1; } if (strlen(iface->ifname) >= sizeof(wpa_s->ifname)) { printf("Too long interface name '%s'.\n", iface->ifname); return -1; } strncpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname)); return 0;}static int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s){#ifdef IEEE8021X_EAPOL struct eapol_ctx *ctx; ctx = malloc(sizeof(*ctx)); if (ctx == NULL) { printf("Failed to allocate EAPOL context.\n"); return -1; } memset(ctx, 0, sizeof(*ctx)); ctx->ctx = wpa_s; ctx->msg_ctx = wpa_s; ctx->eapol_send_ctx = wpa_s; ctx->preauth = 0; ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done; ctx->eapol_send = wpa_supplicant_eapol_send; ctx->set_wep_key = wpa_eapol_set_wep_key; ctx->set_config_blob = wpa_supplicant_set_config_blob; ctx->get_config_blob = wpa_supplicant_get_config_blob; ctx->aborted_cached = wpa_supplicant_aborted_cached; 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; wpa_s->eapol = eapol_sm_init(ctx); if (wpa_s->eapol == NULL) { free(ctx); printf("Failed to initialize EAPOL state machines.\n"); return -1; }#endif /* IEEE8021X_EAPOL */ return 0;}static int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s){#ifndef CONFIG_NO_WPA struct wpa_sm_ctx *ctx; ctx = malloc(sizeof(*ctx)); if (ctx == NULL) { printf("Failed to allocate WPA context.\n"); return -1; } memset(ctx, 0, sizeof(*ctx)); ctx->ctx = wpa_s; ctx->set_state = _wpa_supplicant_set_state; ctx->get_state = _wpa_supplicant_get_state; ctx->req_scan = _wpa_supplicant_req_scan; ctx->deauthenticate = _wpa_supplicant_deauthenticate; ctx->disassociate = _wpa_supplicant_disassociate; ctx->set_key = wpa_supplicant_set_key; ctx->scan = wpa_supplicant_scan; ctx->get_ssid = _wpa_supplicant_get_ssid; ctx->get_bssid = wpa_supplicant_get_bssid; ctx->ether_send = _wpa_ether_send; ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; ctx->alloc_eapol = _wpa_alloc_eapol; ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; ctx->add_pmkid = wpa_supplicant_add_pmkid; ctx->remove_pmkid = wpa_supplicant_remove_pmkid; ctx->set_config_blob = wpa_supplicant_set_config_blob; ctx->get_config_blob = wpa_supplicant_get_config_blob; wpa_s->wpa = wpa_sm_init(ctx); if (wpa_s->wpa == NULL) { fprintf(stderr, "Failed to initialize WPA state machine\n"); return -1; }#endif /* CONFIG_NO_WPA */ return 0;}static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s, int wait_for_interface){ const char *ifname; wpa_printf(MSG_DEBUG, "Initializing interface (2) '%s'", wpa_s->ifname); if (wpa_supplicant_init_eapol(wpa_s) < 0) return -1; /* RSNA Supplicant Key Management - INITIALIZE */ eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); /* Initialize driver interface and register driver event handler before * L2 receive handler so that association events are processed before * EAPOL-Key packets if both become available for the same select() * call. */ wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname); if (wpa_s->drv_priv == NULL) { fprintf(stderr, "Failed to initialize driver interface\n"); return -1; } if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) { fprintf(stderr, "Driver interface rejected driver_param " "'%s'\n", wpa_s->conf->driver_param); return -1; } ifname = wpa_drv_get_ifname(wpa_s); if (ifname && strcmp(ifname, wpa_s->ifname) != 0) { wpa_printf(MSG_DEBUG, "Driver interface replaced interface " "name with '%s'", ifname); strncpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); } if (wpa_supplicant_init_wpa(wpa_s) < 0) return -1; wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname); wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth); wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol); if (wpa_s->conf->dot11RSNAConfigPMKLifetime && wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, wpa_s->conf->dot11RSNAConfigPMKLifetime)) { fprintf(stderr, "Invalid WPA parameter value for " "dot11RSNAConfigPMKLifetime\n"); return -1; } if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold && wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) { fprintf(stderr, "Invalid WPA parameter value for " "dot11RSNAConfigPMKReauthThreshold\n"); return -1; } if (wpa_s->conf->dot11RSNAConfigSATimeout && wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, wpa_s->conf->dot11RSNAConfigSATimeout)) { fprintf(stderr, "Invalid WPA parameter value for " "dot11RSNAConfigSATimeout\n"); return -1; } if (wpa_supplicant_driver_init(wpa_s, wait_for_interface) < 0) { return -1; } wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr); if (wpa_supplicant_ctrl_iface_init(wpa_s)) { printf("Failed to initialize control interface '%s'.\n" "You may have another wpa_supplicant process already " "running or the file was\n" "left by an unclean termination of wpa_supplicant in " "which case you will need\n" "to manually remove this file before starting " "wpa_supplicant again.\n", wpa_s->conf->ctrl_interface); return -1; } return 0;}static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s){ if (wpa_s->drv_priv) { wpa_supplicant_deauthenticate(wpa_s, REASON_DEAUTH_LEAVING); /* Backwards compatibility call to set_wpa() handler. This is * called only just after init and just before deinit, so these * handler can be used to implement same functionality. */ if (wpa_drv_set_wpa(wpa_s, 0) < 0) { fprintf(stderr, "Failed to disable WPA in the " "driver.\n"); } 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); } wpa_supplicant_cleanup(wpa_s);}/** * wpa_supplicant_add_iface - Add a new network interface * @global: Pointer to global data from wpa_supplicant_init() * @iface: Interface configuration options * Returns: Pointer to the created interface or %NULL on failure * * This function is used to add new network interfaces for %wpa_supplicant. * This can be called before wpa_supplicant_run() to add interfaces before the * main event loop has been started. In addition, new interfaces can be added * dynamically while %wpa_supplicant is already running. This could happen, * 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_supplicant *wpa_s; if (global == NULL || iface == NULL) return NULL; wpa_s = wpa_supplicant_alloc(); if (wpa_s == NULL) return NULL; if (wpa_supplicant_init_iface(wpa_s, iface) || wpa_supplicant_init_iface2(wpa_s, global->params.wait_for_interface)) { wpa_printf(MSG_DEBUG, "Failed to add interface %s", iface->ifname); wpa_supplicant_deinit_iface(wpa_s); free(wpa_s); return NULL; } wpa_s->global = global; wpa_s->next = global->ifaces; global->ifaces = wpa_s; wpa_printf(MSG_DEBUG, "Added interface %s", wpa_s->ifname); return wpa_s;}/** * wpa_supplicant_remove_iface - Remove a network interface * @global: Pointer to global data from wpa_supplicant_init() * @wpa_s: Pointer to the network interface to be removed * Returns: 0 if interface was removed, -1 if interface was not found * * This function can be used to dynamically remove network interfaces from * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In * addition, this function is used to remove all remaining interdaces when * %wpa_supplican
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?