eap_gtc.c
Go to the documentation of this file.
00001 /*
00002  * EAP peer method: EAP-GTC (RFC 3748)
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_gtc_data {
00022         int prefix;
00023 };
00024 
00025 
00026 static void * eap_gtc_init(struct eap_sm *sm)
00027 {
00028         struct eap_gtc_data *data;
00029         data = os_zalloc(sizeof(*data));
00030         if (data == NULL)
00031                 return NULL;
00032 
00033         if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
00034             sm->m->method == EAP_TYPE_FAST) {
00035                 wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
00036                            "with challenge/response");
00037                 data->prefix = 1;
00038         }
00039         return data;
00040 }
00041 
00042 
00043 static void eap_gtc_deinit(struct eap_sm *sm, void *priv)
00044 {
00045         struct eap_gtc_data *data = priv;
00046         os_free(data);
00047 }
00048 
00049 
00050 static struct wpabuf * eap_gtc_process(struct eap_sm *sm, void *priv,
00051                                        struct eap_method_ret *ret,
00052                                        const struct wpabuf *reqData)
00053 {
00054         struct eap_gtc_data *data = priv;
00055         struct wpabuf *resp;
00056         const u8 *pos, *password, *identity;
00057         size_t password_len, identity_len, len, plen;
00058         int otp;
00059         u8 id;
00060 
00061         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqData, &len);
00062         if (pos == NULL) {
00063                 ret->ignore = TRUE;
00064                 return NULL;
00065         }
00066         id = eap_get_id(reqData);
00067 
00068         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len);
00069         if (data->prefix &&
00070             (len < 10 || os_memcmp(pos, "CHALLENGE=", 10) != 0)) {
00071                 wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with "
00072                            "expected prefix");
00073 
00074                 /* Send an empty response in order to allow tunneled
00075                  * acknowledgement of the failure. This will also cover the
00076                  * error case which seems to use EAP-MSCHAPv2 like error
00077                  * reporting with EAP-GTC inside EAP-FAST tunnel. */
00078                 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC,
00079                                      0, EAP_CODE_RESPONSE, id);
00080                 return resp;
00081         }
00082 
00083         password = eap_get_config_otp(sm, &password_len);
00084         if (password)
00085                 otp = 1;
00086         else {
00087                 password = eap_get_config_password(sm, &password_len);
00088                 otp = 0;
00089         }
00090 
00091         if (password == NULL) {
00092                 wpa_printf(MSG_INFO, "EAP-GTC: Password not configured");
00093                 eap_sm_request_otp(sm, (const char *) pos, len);
00094                 ret->ignore = TRUE;
00095                 return NULL;
00096         }
00097 
00098         ret->ignore = FALSE;
00099 
00100         ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE;
00101         ret->decision = DECISION_COND_SUCC;
00102         ret->allowNotifications = FALSE;
00103 
00104         plen = password_len;
00105         identity = eap_get_config_identity(sm, &identity_len);
00106         if (identity == NULL)
00107                 return NULL;
00108         if (data->prefix)
00109                 plen += 9 + identity_len + 1;
00110         resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, plen,
00111                              EAP_CODE_RESPONSE, id);
00112         if (resp == NULL)
00113                 return NULL;
00114         if (data->prefix) {
00115                 wpabuf_put_data(resp, "RESPONSE=", 9);
00116                 wpabuf_put_data(resp, identity, identity_len);
00117                 wpabuf_put_u8(resp, '\0');
00118         }
00119         wpabuf_put_data(resp, password, password_len);
00120         wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response",
00121                               wpabuf_head_u8(resp) + sizeof(struct eap_hdr) +
00122                               1, plen);
00123 
00124         if (otp) {
00125                 wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password");
00126                 eap_clear_config_otp(sm);
00127         }
00128 
00129         return resp;
00130 }
00131 
00132 
00133 int eap_peer_gtc_register(void)
00134 {
00135         struct eap_method *eap;
00136         int ret;
00137 
00138         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
00139                                     EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
00140         if (eap == NULL)
00141                 return -1;
00142 
00143         eap->init = eap_gtc_init;
00144         eap->deinit = eap_gtc_deinit;
00145         eap->process = eap_gtc_process;
00146 
00147         ret = eap_peer_method_register(eap);
00148         if (ret)
00149                 eap_peer_method_free(eap);
00150         return ret;
00151 }


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