LCOV - code coverage report
Current view: top level - src/eap_server - eap_server_gtc.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 93 109 85.3 %
Date: 2015-09-27 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / EAP-GTC (RFC 3748)
       3             :  * Copyright (c) 2004-2006, 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 "eap_i.h"
      13             : 
      14             : 
      15             : struct eap_gtc_data {
      16             :         enum { CONTINUE, SUCCESS, FAILURE } state;
      17             :         int prefix;
      18             : };
      19             : 
      20             : 
      21          16 : static void * eap_gtc_init(struct eap_sm *sm)
      22             : {
      23             :         struct eap_gtc_data *data;
      24             : 
      25          16 :         data = os_zalloc(sizeof(*data));
      26          16 :         if (data == NULL)
      27           1 :                 return NULL;
      28          15 :         data->state = CONTINUE;
      29             : 
      30             : #ifdef EAP_SERVER_FAST
      31          30 :         if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
      32          15 :             sm->m->method == EAP_TYPE_FAST) {
      33           7 :                 wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
      34             :                            "with challenge/response");
      35           7 :                 data->prefix = 1;
      36             :         }
      37             : #endif /* EAP_SERVER_FAST */
      38             : 
      39          15 :         return data;
      40             : }
      41             : 
      42             : 
      43          15 : static void eap_gtc_reset(struct eap_sm *sm, void *priv)
      44             : {
      45          15 :         struct eap_gtc_data *data = priv;
      46          15 :         os_free(data);
      47          15 : }
      48             : 
      49             : 
      50          15 : static struct wpabuf * eap_gtc_buildReq(struct eap_sm *sm, void *priv, u8 id)
      51             : {
      52          15 :         struct eap_gtc_data *data = priv;
      53             :         struct wpabuf *req;
      54             :         char *msg;
      55             :         size_t msg_len;
      56             : 
      57          15 :         msg = data->prefix ? "CHALLENGE=Password" : "Password";
      58             : 
      59          15 :         msg_len = os_strlen(msg);
      60          15 :         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, msg_len,
      61             :                             EAP_CODE_REQUEST, id);
      62          15 :         if (req == NULL) {
      63           1 :                 wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for "
      64             :                            "request");
      65           1 :                 data->state = FAILURE;
      66           1 :                 return NULL;
      67             :         }
      68             : 
      69          14 :         wpabuf_put_data(req, msg, msg_len);
      70             : 
      71          14 :         data->state = CONTINUE;
      72             : 
      73          14 :         return req;
      74             : }
      75             : 
      76             : 
      77          14 : static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
      78             :                              struct wpabuf *respData)
      79             : {
      80             :         const u8 *pos;
      81             :         size_t len;
      82             : 
      83          14 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &len);
      84          14 :         if (pos == NULL || len < 1) {
      85           0 :                 wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
      86           0 :                 return TRUE;
      87             :         }
      88             : 
      89          14 :         return FALSE;
      90             : }
      91             : 
      92             : 
      93          14 : static void eap_gtc_process(struct eap_sm *sm, void *priv,
      94             :                             struct wpabuf *respData)
      95             : {
      96          14 :         struct eap_gtc_data *data = priv;
      97             :         const u8 *pos;
      98             :         size_t rlen;
      99             : 
     100          14 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &rlen);
     101          14 :         if (pos == NULL || rlen < 1)
     102           2 :                 return; /* Should not happen - frame already validated */
     103             : 
     104          14 :         wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
     105             : 
     106             : #ifdef EAP_SERVER_FAST
     107          14 :         if (data->prefix) {
     108             :                 const u8 *pos2, *end;
     109             :                 /* "RESPONSE=<user>\0<password>" */
     110           7 :                 if (rlen < 10) {
     111           0 :                         wpa_printf(MSG_DEBUG, "EAP-GTC: Too short response "
     112             :                                    "for EAP-FAST prefix");
     113           0 :                         data->state = FAILURE;
     114           0 :                         return;
     115             :                 }
     116             : 
     117           7 :                 end = pos + rlen;
     118           7 :                 pos += 9;
     119           7 :                 pos2 = pos;
     120          59 :                 while (pos2 < end && *pos2)
     121          45 :                         pos2++;
     122           7 :                 if (pos2 == end) {
     123           0 :                         wpa_printf(MSG_DEBUG, "EAP-GTC: No password in "
     124             :                                    "response to EAP-FAST prefix");
     125           0 :                         data->state = FAILURE;
     126           0 :                         return;
     127             :                 }
     128             : 
     129           7 :                 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Response user",
     130           7 :                                   pos, pos2 - pos);
     131           9 :                 if (sm->identity && sm->require_identity_match &&
     132           3 :                     (pos2 - pos != (int) sm->identity_len ||
     133           1 :                      os_memcmp(pos, sm->identity, sm->identity_len))) {
     134           1 :                         wpa_printf(MSG_DEBUG, "EAP-GTC: Phase 2 Identity did "
     135             :                                    "not match with required Identity");
     136           2 :                         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Expected "
     137             :                                           "identity",
     138           1 :                                           sm->identity, sm->identity_len);
     139           1 :                         data->state = FAILURE;
     140           1 :                         return;
     141             :                 } else {
     142           6 :                         os_free(sm->identity);
     143           6 :                         sm->identity_len = pos2 - pos;
     144           6 :                         sm->identity = os_malloc(sm->identity_len);
     145           6 :                         if (sm->identity == NULL) {
     146           0 :                                 data->state = FAILURE;
     147           0 :                                 return;
     148             :                         }
     149           6 :                         os_memcpy(sm->identity, pos, sm->identity_len);
     150             :                 }
     151             : 
     152           6 :                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
     153           0 :                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-GTC: Phase2 "
     154             :                                           "Identity not found in the user "
     155             :                                           "database",
     156           0 :                                           sm->identity, sm->identity_len);
     157           0 :                         data->state = FAILURE;
     158           0 :                         return;
     159             :                 }
     160             : 
     161           6 :                 pos = pos2 + 1;
     162           6 :                 rlen = end - pos;
     163           6 :                 wpa_hexdump_ascii_key(MSG_MSGDUMP,
     164             :                                       "EAP-GTC: Response password",
     165             :                                       pos, rlen);
     166             :         }
     167             : #endif /* EAP_SERVER_FAST */
     168             : 
     169          25 :         if (sm->user == NULL || sm->user->password == NULL ||
     170          12 :             sm->user->password_hash) {
     171           1 :                 wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not "
     172             :                            "configured");
     173           1 :                 data->state = FAILURE;
     174           1 :                 return;
     175             :         }
     176             : 
     177          23 :         if (rlen != sm->user->password_len ||
     178          11 :             os_memcmp_const(pos, sm->user->password, rlen) != 0) {
     179           1 :                 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
     180           1 :                 data->state = FAILURE;
     181             :         } else {
     182          11 :                 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success");
     183          11 :                 data->state = SUCCESS;
     184             :         }
     185             : }
     186             : 
     187             : 
     188          14 : static Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv)
     189             : {
     190          14 :         struct eap_gtc_data *data = priv;
     191          14 :         return data->state != CONTINUE;
     192             : }
     193             : 
     194             : 
     195          14 : static Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv)
     196             : {
     197          14 :         struct eap_gtc_data *data = priv;
     198          14 :         return data->state == SUCCESS;
     199             : }
     200             : 
     201             : 
     202          25 : int eap_server_gtc_register(void)
     203             : {
     204             :         struct eap_method *eap;
     205             :         int ret;
     206             : 
     207          25 :         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
     208             :                                       EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
     209          25 :         if (eap == NULL)
     210           0 :                 return -1;
     211             : 
     212          25 :         eap->init = eap_gtc_init;
     213          25 :         eap->reset = eap_gtc_reset;
     214          25 :         eap->buildReq = eap_gtc_buildReq;
     215          25 :         eap->check = eap_gtc_check;
     216          25 :         eap->process = eap_gtc_process;
     217          25 :         eap->isDone = eap_gtc_isDone;
     218          25 :         eap->isSuccess = eap_gtc_isSuccess;
     219             : 
     220          25 :         ret = eap_server_method_register(eap);
     221          25 :         if (ret)
     222           0 :                 eap_server_method_free(eap);
     223          25 :         return ret;
     224             : }

Generated by: LCOV version 1.10