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

Generated by: LCOV version 1.10