2 * EAP peer method: EAP-GTC (RFC 3748)
3 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
26 static void * eap_gtc_init(struct eap_sm *sm)
28 struct eap_gtc_data *data;
29 data = os_zalloc(sizeof(*data));
33 if (sm->m && sm->m->method == EAP_TYPE_FAST) {
34 wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
35 "with challenge/response");
42 static void eap_gtc_deinit(struct eap_sm *sm, void *priv)
44 struct eap_gtc_data *data = priv;
49 static u8 * eap_gtc_process(struct eap_sm *sm, void *priv,
50 struct eap_method_ret *ret,
51 const u8 *reqData, size_t reqDataLen,
54 struct eap_gtc_data *data = priv;
55 const struct eap_hdr *req;
57 const u8 *pos, *password, *identity;
59 size_t password_len, identity_len, len, plen;
62 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
63 reqData, reqDataLen, &len);
68 req = (const struct eap_hdr *) reqData;
70 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len);
72 (len < 10 || os_memcmp(pos, "CHALLENGE=", 10) != 0)) {
73 wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with "
76 /* Send an empty response in order to allow tunneled
77 * acknowledgement of the failure. This will also cover the
78 * error case which seems to use EAP-MSCHAPv2 like error
79 * reporting with EAP-GTC inside EAP-FAST tunnel. */
80 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC,
81 respDataLen, 0, EAP_CODE_RESPONSE,
82 req->identifier, NULL);
86 password = eap_get_config_otp(sm, &password_len);
90 password = eap_get_config_password(sm, &password_len);
94 if (password == NULL) {
95 wpa_printf(MSG_INFO, "EAP-GTC: Password not configured");
96 eap_sm_request_otp(sm, (const char *) pos, len);
103 ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE;
104 ret->decision = DECISION_COND_SUCC;
105 ret->allowNotifications = FALSE;
108 identity = eap_get_config_identity(sm, &identity_len);
109 if (identity == NULL)
112 plen += 9 + identity_len + 1;
113 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, respDataLen,
114 plen, EAP_CODE_RESPONSE, req->identifier, &rpos);
118 os_memcpy(rpos, "RESPONSE=", 9);
120 os_memcpy(rpos, identity, identity_len);
121 rpos += identity_len;
124 os_memcpy(rpos, password, password_len);
125 wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response",
126 (u8 *) (resp + 1) + 1, plen);
129 wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password");
130 eap_clear_config_otp(sm);
137 int eap_peer_gtc_register(void)
139 struct eap_method *eap;
142 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
143 EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
147 eap->init = eap_gtc_init;
148 eap->deinit = eap_gtc_deinit;
149 eap->process = eap_gtc_process;
151 ret = eap_peer_method_register(eap);
153 eap_peer_method_free(eap);