LCOV - code coverage report
Current view: top level - src/rsn_supp - preauth.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 147 206 71.4 %
Date: 2014-05-28 Functions: 11 13 84.6 %

          Line data    Source code
       1             : /*
       2             :  * RSN pre-authentication (supplicant)
       3             :  * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "wpa.h"
      13             : #include "eloop.h"
      14             : #include "l2_packet/l2_packet.h"
      15             : #include "eapol_supp/eapol_supp_sm.h"
      16             : #include "preauth.h"
      17             : #include "pmksa_cache.h"
      18             : #include "wpa_i.h"
      19             : 
      20             : 
      21             : #ifdef IEEE8021X_EAPOL
      22             : 
      23             : #define PMKID_CANDIDATE_PRIO_SCAN 1000
      24             : 
      25             : 
      26             : struct rsn_pmksa_candidate {
      27             :         struct dl_list list;
      28             :         u8 bssid[ETH_ALEN];
      29             :         int priority;
      30             : };
      31             : 
      32             : 
      33             : /**
      34             :  * pmksa_candidate_free - Free all entries in PMKSA candidate list
      35             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
      36             :  */
      37         185 : void pmksa_candidate_free(struct wpa_sm *sm)
      38             : {
      39             :         struct rsn_pmksa_candidate *entry, *n;
      40             : 
      41         185 :         if (sm == NULL)
      42         194 :                 return;
      43             : 
      44         176 :         dl_list_for_each_safe(entry, n, &sm->pmksa_candidates,
      45             :                               struct rsn_pmksa_candidate, list) {
      46           0 :                 dl_list_del(&entry->list);
      47           0 :                 os_free(entry);
      48             :         }
      49             : }
      50             : 
      51             : 
      52           4 : static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
      53             :                                 const u8 *buf, size_t len)
      54             : {
      55           4 :         struct wpa_sm *sm = ctx;
      56             : 
      57           4 :         wpa_printf(MSG_DEBUG, "RX pre-auth from " MACSTR, MAC2STR(src_addr));
      58           4 :         wpa_hexdump(MSG_MSGDUMP, "RX pre-auth", buf, len);
      59             : 
      60           8 :         if (sm->preauth_eapol == NULL ||
      61           8 :             is_zero_ether_addr(sm->preauth_bssid) ||
      62           4 :             os_memcmp(sm->preauth_bssid, src_addr, ETH_ALEN) != 0) {
      63           0 :                 wpa_printf(MSG_WARNING, "RSN pre-auth frame received from "
      64             :                            "unexpected source " MACSTR " - dropped",
      65           0 :                            MAC2STR(src_addr));
      66           4 :                 return;
      67             :         }
      68             : 
      69           4 :         eapol_sm_rx_eapol(sm->preauth_eapol, src_addr, buf, len);
      70             : }
      71             : 
      72             : 
      73           1 : static void rsn_preauth_eapol_cb(struct eapol_sm *eapol,
      74             :                                  enum eapol_supp_result result,
      75             :                                  void *ctx)
      76             : {
      77           1 :         struct wpa_sm *sm = ctx;
      78             :         u8 pmk[PMK_LEN];
      79             : 
      80           1 :         if (result == EAPOL_SUPP_RESULT_SUCCESS) {
      81             :                 int res, pmk_len;
      82           1 :                 pmk_len = PMK_LEN;
      83           1 :                 res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
      84           1 :                 if (res) {
      85             :                         /*
      86             :                          * EAP-LEAP is an exception from other EAP methods: it
      87             :                          * uses only 16-byte PMK.
      88             :                          */
      89           0 :                         res = eapol_sm_get_key(eapol, pmk, 16);
      90           0 :                         pmk_len = 16;
      91             :                 }
      92           1 :                 if (res == 0) {
      93           1 :                         wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth",
      94             :                                         pmk, pmk_len);
      95           1 :                         sm->pmk_len = pmk_len;
      96           2 :                         pmksa_cache_add(sm->pmksa, pmk, pmk_len,
      97           1 :                                         sm->preauth_bssid, sm->own_addr,
      98             :                                         sm->network_ctx,
      99             :                                         WPA_KEY_MGMT_IEEE8021X);
     100             :                 } else {
     101           0 :                         wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
     102             :                                 "RSN: failed to get master session key from "
     103             :                                 "pre-auth EAPOL state machines");
     104           0 :                         result = EAPOL_SUPP_RESULT_FAILURE;
     105             :                 }
     106             :         }
     107             : 
     108           7 :         wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "RSN: pre-authentication with "
     109           6 :                 MACSTR " %s", MAC2STR(sm->preauth_bssid),
     110             :                 result == EAPOL_SUPP_RESULT_SUCCESS ? "completed successfully" :
     111             :                 "failed");
     112             : 
     113           1 :         rsn_preauth_deinit(sm);
     114           1 :         rsn_preauth_candidate_process(sm);
     115           1 : }
     116             : 
     117             : 
     118           0 : static void rsn_preauth_timeout(void *eloop_ctx, void *timeout_ctx)
     119             : {
     120           0 :         struct wpa_sm *sm = eloop_ctx;
     121             : 
     122           0 :         wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "RSN: pre-authentication with "
     123           0 :                 MACSTR " timed out", MAC2STR(sm->preauth_bssid));
     124           0 :         rsn_preauth_deinit(sm);
     125           0 :         rsn_preauth_candidate_process(sm);
     126           0 : }
     127             : 
     128             : 
     129           4 : static int rsn_preauth_eapol_send(void *ctx, int type, const u8 *buf,
     130             :                                   size_t len)
     131             : {
     132           4 :         struct wpa_sm *sm = ctx;
     133             :         u8 *msg;
     134             :         size_t msglen;
     135             :         int res;
     136             : 
     137             :         /* TODO: could add l2_packet_sendmsg that allows fragments to avoid
     138             :          * extra copy here */
     139             : 
     140           4 :         if (sm->l2_preauth == NULL)
     141           0 :                 return -1;
     142             : 
     143           4 :         msg = wpa_sm_alloc_eapol(sm, type, buf, len, &msglen, NULL);
     144           4 :         if (msg == NULL)
     145           0 :                 return -1;
     146             : 
     147           4 :         wpa_hexdump(MSG_MSGDUMP, "TX EAPOL (preauth)", msg, msglen);
     148           4 :         res = l2_packet_send(sm->l2_preauth, sm->preauth_bssid,
     149             :                              ETH_P_RSN_PREAUTH, msg, msglen);
     150           4 :         os_free(msg);
     151           4 :         return res;
     152             : }
     153             : 
     154             : 
     155             : /**
     156             :  * rsn_preauth_init - Start new RSN pre-authentication
     157             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     158             :  * @dst: Authenticator address (BSSID) with which to preauthenticate
     159             :  * @eap_conf: Current EAP configuration
     160             :  * Returns: 0 on success, -1 on another pre-authentication is in progress,
     161             :  * -2 on layer 2 packet initialization failure, -3 on EAPOL state machine
     162             :  * initialization failure, -4 on memory allocation failure
     163             :  *
     164             :  * This function request an RSN pre-authentication with a given destination
     165             :  * address. This is usually called for PMKSA candidates found from scan results
     166             :  * or from driver reports. In addition, ctrl_iface PREAUTH command can trigger
     167             :  * pre-authentication.
     168             :  */
     169           2 : int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
     170             :                      struct eap_peer_config *eap_conf)
     171             : {
     172             :         struct eapol_config eapol_conf;
     173             :         struct eapol_ctx *ctx;
     174             : 
     175           2 :         if (sm->preauth_eapol)
     176           0 :                 return -1;
     177             : 
     178          12 :         wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
     179          12 :                 "RSN: starting pre-authentication with " MACSTR, MAC2STR(dst));
     180             : 
     181           2 :         sm->l2_preauth = l2_packet_init(sm->ifname, sm->own_addr,
     182             :                                         ETH_P_RSN_PREAUTH,
     183             :                                         rsn_preauth_receive, sm, 0);
     184           2 :         if (sm->l2_preauth == NULL) {
     185           0 :                 wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet "
     186             :                            "processing for pre-authentication");
     187           0 :                 return -2;
     188             :         }
     189             : 
     190           2 :         if (sm->bridge_ifname) {
     191           0 :                 sm->l2_preauth_br = l2_packet_init(sm->bridge_ifname,
     192           0 :                                                    sm->own_addr,
     193             :                                                    ETH_P_RSN_PREAUTH,
     194             :                                                    rsn_preauth_receive, sm, 0);
     195           0 :                 if (sm->l2_preauth_br == NULL) {
     196           0 :                         wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 "
     197             :                                    "packet processing (bridge) for "
     198             :                                    "pre-authentication");
     199           0 :                         return -2;
     200             :                 }
     201             :         }
     202             : 
     203           2 :         ctx = os_zalloc(sizeof(*ctx));
     204           2 :         if (ctx == NULL) {
     205           0 :                 wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context.");
     206           0 :                 return -4;
     207             :         }
     208           2 :         ctx->ctx = sm->ctx->ctx;
     209           2 :         ctx->msg_ctx = sm->ctx->ctx;
     210           2 :         ctx->preauth = 1;
     211           2 :         ctx->cb = rsn_preauth_eapol_cb;
     212           2 :         ctx->cb_ctx = sm;
     213           2 :         ctx->scard_ctx = sm->scard_ctx;
     214           2 :         ctx->eapol_send = rsn_preauth_eapol_send;
     215           2 :         ctx->eapol_send_ctx = sm;
     216           2 :         ctx->set_config_blob = sm->ctx->set_config_blob;
     217           2 :         ctx->get_config_blob = sm->ctx->get_config_blob;
     218             : 
     219           2 :         sm->preauth_eapol = eapol_sm_init(ctx);
     220           2 :         if (sm->preauth_eapol == NULL) {
     221           0 :                 os_free(ctx);
     222           0 :                 wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL "
     223             :                            "state machines for pre-authentication");
     224           0 :                 return -3;
     225             :         }
     226           2 :         os_memset(&eapol_conf, 0, sizeof(eapol_conf));
     227           2 :         eapol_conf.accept_802_1x_keys = 0;
     228           2 :         eapol_conf.required_keys = 0;
     229           2 :         eapol_conf.fast_reauth = sm->fast_reauth;
     230           2 :         eapol_conf.workaround = sm->eap_workaround;
     231           2 :         eapol_sm_notify_config(sm->preauth_eapol, eap_conf, &eapol_conf);
     232             :         /*
     233             :          * Use a shorter startPeriod with preauthentication since the first
     234             :          * preauth EAPOL-Start frame may end up being dropped due to race
     235             :          * condition in the AP between the data receive and key configuration
     236             :          * after the 4-Way Handshake.
     237             :          */
     238           2 :         eapol_sm_configure(sm->preauth_eapol, -1, -1, 5, 6);
     239           2 :         os_memcpy(sm->preauth_bssid, dst, ETH_ALEN);
     240             : 
     241           2 :         eapol_sm_notify_portValid(sm->preauth_eapol, TRUE);
     242             :         /* 802.1X::portControl = Auto */
     243           2 :         eapol_sm_notify_portEnabled(sm->preauth_eapol, TRUE);
     244             : 
     245           2 :         eloop_register_timeout(sm->dot11RSNAConfigSATimeout, 0,
     246             :                                rsn_preauth_timeout, sm, NULL);
     247             : 
     248           2 :         return 0;
     249             : }
     250             : 
     251             : 
     252             : /**
     253             :  * rsn_preauth_deinit - Abort RSN pre-authentication
     254             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     255             :  *
     256             :  * This function aborts the current RSN pre-authentication (if one is started)
     257             :  * and frees resources allocated for it.
     258             :  */
     259        1162 : void rsn_preauth_deinit(struct wpa_sm *sm)
     260             : {
     261        1162 :         if (sm == NULL || !sm->preauth_eapol)
     262        2322 :                 return;
     263             : 
     264           2 :         eloop_cancel_timeout(rsn_preauth_timeout, sm, NULL);
     265           2 :         eapol_sm_deinit(sm->preauth_eapol);
     266           2 :         sm->preauth_eapol = NULL;
     267           2 :         os_memset(sm->preauth_bssid, 0, ETH_ALEN);
     268             : 
     269           2 :         l2_packet_deinit(sm->l2_preauth);
     270           2 :         sm->l2_preauth = NULL;
     271           2 :         if (sm->l2_preauth_br) {
     272           0 :                 l2_packet_deinit(sm->l2_preauth_br);
     273           0 :                 sm->l2_preauth_br = NULL;
     274             :         }
     275             : }
     276             : 
     277             : 
     278             : /**
     279             :  * rsn_preauth_candidate_process - Process PMKSA candidates
     280             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     281             :  *
     282             :  * Go through the PMKSA candidates and start pre-authentication if a candidate
     283             :  * without an existing PMKSA cache entry is found. Processed candidates will be
     284             :  * removed from the list.
     285             :  */
     286         624 : void rsn_preauth_candidate_process(struct wpa_sm *sm)
     287             : {
     288             :         struct rsn_pmksa_candidate *candidate, *n;
     289             : 
     290         624 :         if (dl_list_empty(&sm->pmksa_candidates))
     291         623 :                 return;
     292             : 
     293             :         /* TODO: drop priority for old candidate entries */
     294             : 
     295           1 :         wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: processing PMKSA candidate "
     296             :                 "list");
     297           2 :         if (sm->preauth_eapol ||
     298           2 :             sm->proto != WPA_PROTO_RSN ||
     299           2 :             wpa_sm_get_state(sm) != WPA_COMPLETED ||
     300           1 :             (sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
     301           0 :              sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256)) {
     302           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
     303             :                         "state for new pre-authentication");
     304           0 :                 return; /* invalid state for new pre-auth */
     305             :         }
     306             : 
     307           1 :         dl_list_for_each_safe(candidate, n, &sm->pmksa_candidates,
     308             :                               struct rsn_pmksa_candidate, list) {
     309           1 :                 struct rsn_pmksa_cache_entry *p = NULL;
     310           1 :                 p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL, NULL);
     311           1 :                 if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 &&
     312           0 :                     (p == NULL || p->opportunistic)) {
     313           6 :                         wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA "
     314             :                                 "candidate " MACSTR
     315             :                                 " selected for pre-authentication",
     316           6 :                                 MAC2STR(candidate->bssid));
     317           1 :                         dl_list_del(&candidate->list);
     318           1 :                         rsn_preauth_init(sm, candidate->bssid,
     319           1 :                                          sm->eap_conf_ctx);
     320           1 :                         os_free(candidate);
     321           1 :                         return;
     322             :                 }
     323           0 :                 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA candidate "
     324             :                         MACSTR " does not need pre-authentication anymore",
     325           0 :                         MAC2STR(candidate->bssid));
     326             :                 /* Some drivers (e.g., NDIS) expect to get notified about the
     327             :                  * PMKIDs again, so report the existing data now. */
     328           0 :                 if (p) {
     329           0 :                         wpa_sm_add_pmkid(sm, candidate->bssid, p->pmkid);
     330             :                 }
     331             : 
     332           0 :                 dl_list_del(&candidate->list);
     333           0 :                 os_free(candidate);
     334             :         }
     335           0 :         wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: no more pending PMKSA "
     336             :                 "candidates");
     337             : }
     338             : 
     339             : 
     340             : /**
     341             :  * pmksa_candidate_add - Add a new PMKSA candidate
     342             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     343             :  * @bssid: BSSID (authenticator address) of the candidate
     344             :  * @prio: Priority (the smaller number, the higher priority)
     345             :  * @preauth: Whether the candidate AP advertises support for pre-authentication
     346             :  *
     347             :  * This function is used to add PMKSA candidates for RSN pre-authentication. It
     348             :  * is called from scan result processing and from driver events for PMKSA
     349             :  * candidates, i.e., EVENT_PMKID_CANDIDATE events to wpa_supplicant_event().
     350             :  */
     351          10 : void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid,
     352             :                          int prio, int preauth)
     353             : {
     354             :         struct rsn_pmksa_candidate *cand, *pos;
     355             : 
     356          10 :         if (sm->network_ctx && sm->proactive_key_caching)
     357           3 :                 pmksa_cache_get_opportunistic(sm->pmksa, sm->network_ctx,
     358             :                                               bssid);
     359             : 
     360          10 :         if (!preauth) {
     361           9 :                 wpa_printf(MSG_DEBUG, "RSN: Ignored PMKID candidate without "
     362             :                            "preauth flag");
     363           9 :                 return;
     364             :         }
     365             : 
     366             :         /* If BSSID already on candidate list, update the priority of the old
     367             :          * entry. Do not override priority based on normal scan results. */
     368           1 :         cand = NULL;
     369           1 :         dl_list_for_each(pos, &sm->pmksa_candidates,
     370             :                          struct rsn_pmksa_candidate, list) {
     371           0 :                 if (os_memcmp(pos->bssid, bssid, ETH_ALEN) == 0) {
     372           0 :                         cand = pos;
     373           0 :                         break;
     374             :                 }
     375             :         }
     376             : 
     377           1 :         if (cand) {
     378           0 :                 dl_list_del(&cand->list);
     379           0 :                 if (prio < PMKID_CANDIDATE_PRIO_SCAN)
     380           0 :                         cand->priority = prio;
     381             :         } else {
     382           1 :                 cand = os_zalloc(sizeof(*cand));
     383           1 :                 if (cand == NULL)
     384           0 :                         return;
     385           1 :                 os_memcpy(cand->bssid, bssid, ETH_ALEN);
     386           1 :                 cand->priority = prio;
     387             :         }
     388             : 
     389             :         /* Add candidate to the list; order by increasing priority value. i.e.,
     390             :          * highest priority (smallest value) first. */
     391           1 :         dl_list_for_each(pos, &sm->pmksa_candidates,
     392             :                          struct rsn_pmksa_candidate, list) {
     393           0 :                 if (cand->priority <= pos->priority) {
     394           0 :                         dl_list_add(pos->list.prev, &cand->list);
     395           0 :                         cand = NULL;
     396           0 :                         break;
     397             :                 }
     398             :         }
     399           1 :         if (cand)
     400           1 :                 dl_list_add_tail(&sm->pmksa_candidates, &cand->list);
     401             : 
     402           6 :         wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: added PMKSA cache "
     403           6 :                 "candidate " MACSTR " prio %d", MAC2STR(bssid), prio);
     404           1 :         rsn_preauth_candidate_process(sm);
     405             : }
     406             : 
     407             : 
     408             : /* TODO: schedule periodic scans if current AP supports preauth */
     409             : 
     410             : /**
     411             :  * rsn_preauth_scan_results - Start processing scan results for canditates
     412             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     413             :  * Returns: 0 if ready to process results or -1 to skip processing
     414             :  *
     415             :  * This functions is used to notify RSN code about start of new scan results
     416             :  * processing. The actual scan results will be provided by calling
     417             :  * rsn_preauth_scan_result() for each BSS if this function returned 0.
     418             :  */
     419         744 : int rsn_preauth_scan_results(struct wpa_sm *sm)
     420             : {
     421         744 :         if (sm->ssid_len == 0)
     422         637 :                 return -1;
     423             : 
     424             :         /*
     425             :          * TODO: is it ok to free all candidates? What about the entries
     426             :          * received from EVENT_PMKID_CANDIDATE?
     427             :          */
     428         107 :         pmksa_candidate_free(sm);
     429             : 
     430         107 :         return 0;
     431             : }
     432             : 
     433             : 
     434             : /**
     435             :  * rsn_preauth_scan_result - Processing scan result for PMKSA canditates
     436             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     437             :  *
     438             :  * Add all suitable APs (Authenticators) from scan results into PMKSA
     439             :  * candidate list.
     440             :  */
     441          91 : void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
     442             :                              const u8 *ssid, const u8 *rsn)
     443             : {
     444             :         struct wpa_ie_data ie;
     445             :         struct rsn_pmksa_cache_entry *pmksa;
     446             : 
     447         177 :         if (ssid[1] != sm->ssid_len ||
     448          86 :             os_memcmp(ssid + 2, sm->ssid, sm->ssid_len) != 0)
     449          90 :                 return; /* Not for the current SSID */
     450             : 
     451          82 :         if (os_memcmp(bssid, sm->bssid, ETH_ALEN) == 0)
     452          67 :                 return; /* Ignore current AP */
     453             : 
     454          15 :         if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
     455           0 :                 return;
     456             : 
     457          15 :         pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL, NULL);
     458          15 :         if (pmksa && (!pmksa->opportunistic ||
     459           0 :                       !(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
     460           5 :                 return;
     461             : 
     462             :         /* Give less priority to candidates found from normal scan results. */
     463          10 :         pmksa_candidate_add(sm, bssid, PMKID_CANDIDATE_PRIO_SCAN,
     464          10 :                             ie.capabilities & WPA_CAPABILITY_PREAUTH);
     465             : }
     466             : 
     467             : 
     468             : #ifdef CONFIG_CTRL_IFACE
     469             : /**
     470             :  * rsn_preauth_get_status - Get pre-authentication status
     471             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     472             :  * @buf: Buffer for status information
     473             :  * @buflen: Maximum buffer length
     474             :  * @verbose: Whether to include verbose status information
     475             :  * Returns: Number of bytes written to buf.
     476             :  *
     477             :  * Query WPA2 pre-authentication for status information. This function fills in
     478             :  * a text area with current status information. If the buffer (buf) is not
     479             :  * large enough, status information will be truncated to fit the buffer.
     480             :  */
     481         755 : int rsn_preauth_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
     482             :                            int verbose)
     483             : {
     484         755 :         char *pos = buf, *end = buf + buflen;
     485             :         int res, ret;
     486             : 
     487         755 :         if (sm->preauth_eapol) {
     488           1 :                 ret = os_snprintf(pos, end - pos, "Pre-authentication "
     489             :                                   "EAPOL state machines:\n");
     490           1 :                 if (ret < 0 || ret >= end - pos)
     491           0 :                         return pos - buf;
     492           1 :                 pos += ret;
     493           1 :                 res = eapol_sm_get_status(sm->preauth_eapol,
     494           1 :                                           pos, end - pos, verbose);
     495           1 :                 if (res >= 0)
     496           1 :                         pos += res;
     497             :         }
     498             : 
     499         755 :         return pos - buf;
     500             : }
     501             : #endif /* CONFIG_CTRL_IFACE */
     502             : 
     503             : 
     504             : /**
     505             :  * rsn_preauth_in_progress - Verify whether pre-authentication is in progress
     506             :  * @sm: Pointer to WPA state machine data from wpa_sm_init()
     507             :  */
     508           0 : int rsn_preauth_in_progress(struct wpa_sm *sm)
     509             : {
     510           0 :         return sm->preauth_eapol != NULL;
     511             : }
     512             : 
     513             : #endif /* IEEE8021X_EAPOL */

Generated by: LCOV version 1.10