eap_gtc.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "eap_i.h"
00020 
00021 
00022 struct eap_gtc_data {
00023         enum { CONTINUE, SUCCESS, FAILURE } state;
00024         int prefix;
00025 };
00026 
00027 
00028 static void * eap_gtc_init(struct eap_sm *sm)
00029 {
00030         struct eap_gtc_data *data;
00031 
00032         data = os_zalloc(sizeof(*data));
00033         if (data == NULL)
00034                 return NULL;
00035         data->state = CONTINUE;
00036 
00037 #ifdef EAP_SERVER_FAST
00038         if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
00039             sm->m->method == EAP_TYPE_FAST) {
00040                 wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
00041                            "with challenge/response");
00042                 data->prefix = 1;
00043         }
00044 #endif /* EAP_SERVER_FAST */
00045 
00046         return data;
00047 }
00048 
00049 
00050 static void eap_gtc_reset(struct eap_sm *sm, void *priv)
00051 {
00052         struct eap_gtc_data *data = priv;
00053         os_free(data);
00054 }
00055 
00056 
00057 static struct wpabuf * eap_gtc_buildReq(struct eap_sm *sm, void *priv, u8 id)
00058 {
00059         struct eap_gtc_data *data = priv;
00060         struct wpabuf *req;
00061         char *msg;
00062         size_t msg_len;
00063 
00064         msg = data->prefix ? "CHALLENGE=Password" : "Password";
00065 
00066         msg_len = os_strlen(msg);
00067         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, msg_len,
00068                             EAP_CODE_REQUEST, id);
00069         if (req == NULL) {
00070                 wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for "
00071                            "request");
00072                 data->state = FAILURE;
00073                 return NULL;
00074         }
00075 
00076         wpabuf_put_data(req, msg, msg_len);
00077 
00078         data->state = CONTINUE;
00079 
00080         return req;
00081 }
00082 
00083 
00084 static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
00085                              struct wpabuf *respData)
00086 {
00087         const u8 *pos;
00088         size_t len;
00089 
00090         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &len);
00091         if (pos == NULL || len < 1) {
00092                 wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
00093                 return TRUE;
00094         }
00095 
00096         return FALSE;
00097 }
00098 
00099 
00100 static void eap_gtc_process(struct eap_sm *sm, void *priv,
00101                             struct wpabuf *respData)
00102 {
00103         struct eap_gtc_data *data = priv;
00104         const u8 *pos;
00105         size_t rlen;
00106 
00107         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &rlen);
00108         if (pos == NULL || rlen < 1)
00109                 return; /* Should not happen - frame already validated */
00110 
00111         wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
00112 
00113 #ifdef EAP_SERVER_FAST
00114         if (data->prefix) {
00115                 const u8 *pos2, *end;
00116                 /* "RESPONSE=<user>\0<password>" */
00117                 if (rlen < 10) {
00118                         wpa_printf(MSG_DEBUG, "EAP-GTC: Too short response "
00119                                    "for EAP-FAST prefix");
00120                         data->state = FAILURE;
00121                         return;
00122                 }
00123 
00124                 end = pos + rlen;
00125                 pos += 9;
00126                 pos2 = pos;
00127                 while (pos2 < end && *pos2)
00128                         pos2++;
00129                 if (pos2 == end) {
00130                         wpa_printf(MSG_DEBUG, "EAP-GTC: No password in "
00131                                    "response to EAP-FAST prefix");
00132                         data->state = FAILURE;
00133                         return;
00134                 }
00135 
00136                 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Response user",
00137                                   pos, pos2 - pos);
00138                 if (sm->identity && sm->require_identity_match &&
00139                     (pos2 - pos != (int) sm->identity_len ||
00140                      os_memcmp(pos, sm->identity, sm->identity_len))) {
00141                         wpa_printf(MSG_DEBUG, "EAP-GTC: Phase 2 Identity did "
00142                                    "not match with required Identity");
00143                         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Expected "
00144                                           "identity",
00145                                           sm->identity, sm->identity_len);
00146                         data->state = FAILURE;
00147                         return;
00148                 } else {
00149                         os_free(sm->identity);
00150                         sm->identity_len = pos2 - pos;
00151                         sm->identity = os_malloc(sm->identity_len);
00152                         if (sm->identity == NULL) {
00153                                 data->state = FAILURE;
00154                                 return;
00155                         }
00156                         os_memcpy(sm->identity, pos, sm->identity_len);
00157                 }
00158 
00159                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
00160                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-GTC: Phase2 "
00161                                           "Identity not found in the user "
00162                                           "database",
00163                                           sm->identity, sm->identity_len);
00164                         data->state = FAILURE;
00165                         return;
00166                 }
00167 
00168                 pos = pos2 + 1;
00169                 rlen = end - pos;
00170                 wpa_hexdump_ascii_key(MSG_MSGDUMP,
00171                                       "EAP-GTC: Response password",
00172                                       pos, rlen);
00173         }
00174 #endif /* EAP_SERVER_FAST */
00175 
00176         if (sm->user == NULL || sm->user->password == NULL ||
00177             sm->user->password_hash) {
00178                 wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not "
00179                            "configured");
00180                 data->state = FAILURE;
00181                 return;
00182         }
00183 
00184         if (rlen != sm->user->password_len ||
00185             os_memcmp(pos, sm->user->password, rlen) != 0) {
00186                 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
00187                 data->state = FAILURE;
00188         } else {
00189                 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success");
00190                 data->state = SUCCESS;
00191         }
00192 }
00193 
00194 
00195 static Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv)
00196 {
00197         struct eap_gtc_data *data = priv;
00198         return data->state != CONTINUE;
00199 }
00200 
00201 
00202 static Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv)
00203 {
00204         struct eap_gtc_data *data = priv;
00205         return data->state == SUCCESS;
00206 }
00207 
00208 
00209 int eap_server_gtc_register(void)
00210 {
00211         struct eap_method *eap;
00212         int ret;
00213 
00214         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
00215                                       EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
00216         if (eap == NULL)
00217                 return -1;
00218 
00219         eap->init = eap_gtc_init;
00220         eap->reset = eap_gtc_reset;
00221         eap->buildReq = eap_gtc_buildReq;
00222         eap->check = eap_gtc_check;
00223         eap->process = eap_gtc_process;
00224         eap->isDone = eap_gtc_isDone;
00225         eap->isSuccess = eap_gtc_isSuccess;
00226 
00227         ret = eap_server_method_register(eap);
00228         if (ret)
00229                 eap_server_method_free(eap);
00230         return ret;
00231 }
00232 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:51 2009 for hostapd by  doxygen 1.6.1