eap_server_identity.c
Go to the documentation of this file.
00001 /*
00002  * hostapd / EAP-Identity
00003  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "eap_i.h"
00019 
00020 
00021 struct eap_identity_data {
00022         enum { CONTINUE, SUCCESS, FAILURE } state;
00023         int pick_up;
00024 };
00025 
00026 
00027 static void * eap_identity_init(struct eap_sm *sm)
00028 {
00029         struct eap_identity_data *data;
00030 
00031         data = os_zalloc(sizeof(*data));
00032         if (data == NULL)
00033                 return NULL;
00034         data->state = CONTINUE;
00035 
00036         return data;
00037 }
00038 
00039 
00040 static void * eap_identity_initPickUp(struct eap_sm *sm)
00041 {
00042         struct eap_identity_data *data;
00043         data = eap_identity_init(sm);
00044         if (data) {
00045                 data->pick_up = 1;
00046         }
00047         return data;
00048 }
00049 
00050 
00051 static void eap_identity_reset(struct eap_sm *sm, void *priv)
00052 {
00053         struct eap_identity_data *data = priv;
00054         os_free(data);
00055 }
00056 
00057 
00058 static struct wpabuf * eap_identity_buildReq(struct eap_sm *sm, void *priv,
00059                                              u8 id)
00060 {
00061         struct eap_identity_data *data = priv;
00062         struct wpabuf *req;
00063         const char *req_data;
00064         size_t req_data_len;
00065 
00066         if (sm->eapol_cb->get_eap_req_id_text) {
00067                 req_data = sm->eapol_cb->get_eap_req_id_text(sm->eapol_ctx,
00068                                                              &req_data_len);
00069         } else {
00070                 req_data = NULL;
00071                 req_data_len = 0;
00072         }
00073         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req_data_len,
00074                             EAP_CODE_REQUEST, id);
00075         if (req == NULL) {
00076                 wpa_printf(MSG_ERROR, "EAP-Identity: Failed to allocate "
00077                            "memory for request");
00078                 data->state = FAILURE;
00079                 return NULL;
00080         }
00081 
00082         wpabuf_put_data(req, req_data, req_data_len);
00083 
00084         return req;
00085 }
00086 
00087 
00088 static Boolean eap_identity_check(struct eap_sm *sm, void *priv,
00089                                   struct wpabuf *respData)
00090 {
00091         const u8 *pos;
00092         size_t len;
00093 
00094         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
00095                                respData, &len);
00096         if (pos == NULL) {
00097                 wpa_printf(MSG_INFO, "EAP-Identity: Invalid frame");
00098                 return TRUE;
00099         }
00100 
00101         return FALSE;
00102 }
00103 
00104 
00105 static void eap_identity_process(struct eap_sm *sm, void *priv,
00106                                  struct wpabuf *respData)
00107 {
00108         struct eap_identity_data *data = priv;
00109         const u8 *pos;
00110         size_t len;
00111 
00112         if (data->pick_up) {
00113                 if (eap_identity_check(sm, data, respData)) {
00114                         wpa_printf(MSG_DEBUG, "EAP-Identity: failed to pick "
00115                                    "up already started negotiation");
00116                         data->state = FAILURE;
00117                         return;
00118                 }
00119                 data->pick_up = 0;
00120         }
00121 
00122         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
00123                                respData, &len);
00124         if (pos == NULL)
00125                 return; /* Should not happen - frame already validated */
00126 
00127         wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len);
00128         if (sm->identity)
00129                 sm->update_user = TRUE;
00130         os_free(sm->identity);
00131         sm->identity = os_malloc(len ? len : 1);
00132         if (sm->identity == NULL) {
00133                 data->state = FAILURE;
00134         } else {
00135                 os_memcpy(sm->identity, pos, len);
00136                 sm->identity_len = len;
00137                 data->state = SUCCESS;
00138         }
00139 }
00140 
00141 
00142 static Boolean eap_identity_isDone(struct eap_sm *sm, void *priv)
00143 {
00144         struct eap_identity_data *data = priv;
00145         return data->state != CONTINUE;
00146 }
00147 
00148 
00149 static Boolean eap_identity_isSuccess(struct eap_sm *sm, void *priv)
00150 {
00151         struct eap_identity_data *data = priv;
00152         return data->state == SUCCESS;
00153 }
00154 
00155 
00156 int eap_server_identity_register(void)
00157 {
00158         struct eap_method *eap;
00159         int ret;
00160 
00161         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
00162                                       EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
00163                                       "Identity");
00164         if (eap == NULL)
00165                 return -1;
00166 
00167         eap->init = eap_identity_init;
00168         eap->initPickUp = eap_identity_initPickUp;
00169         eap->reset = eap_identity_reset;
00170         eap->buildReq = eap_identity_buildReq;
00171         eap->check = eap_identity_check;
00172         eap->process = eap_identity_process;
00173         eap->isDone = eap_identity_isDone;
00174         eap->isSuccess = eap_identity_isSuccess;
00175 
00176         ret = eap_server_method_register(eap);
00177         if (ret)
00178                 eap_server_method_free(eap);
00179         return ret;
00180 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34