wpa_supplicant: update vendor branch to 0.6.10
[dragonfly.git] / contrib / hostapd / eap_gtc.c
1 /*
2  * hostapd / EAP-GTC (RFC 3748)
3  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "hostapd.h"
18 #include "common.h"
19 #include "eap_i.h"
20
21
22 struct eap_gtc_data {
23         enum { CONTINUE, SUCCESS, FAILURE } state;
24 };
25
26
27 static void * eap_gtc_init(struct eap_sm *sm)
28 {
29         struct eap_gtc_data *data;
30
31         data = wpa_zalloc(sizeof(*data));
32         if (data == NULL)
33                 return NULL;
34         data->state = CONTINUE;
35
36         return data;
37 }
38
39
40 static void eap_gtc_reset(struct eap_sm *sm, void *priv)
41 {
42         struct eap_gtc_data *data = priv;
43         free(data);
44 }
45
46
47 static u8 * eap_gtc_buildReq(struct eap_sm *sm, void *priv, int id,
48                              size_t *reqDataLen)
49 {
50         struct eap_gtc_data *data = priv;
51         struct eap_hdr *req;
52         u8 *pos;
53         char *msg = "Password";
54         size_t msg_len;
55
56         msg_len = strlen(msg);
57         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqDataLen,
58                             msg_len, EAP_CODE_REQUEST, id, &pos);
59         if (req == NULL) {
60                 wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for "
61                            "request");
62                 data->state = FAILURE;
63                 return NULL;
64         }
65
66         memcpy(pos, msg, msg_len);
67
68         data->state = CONTINUE;
69
70         return (u8 *) req;
71 }
72
73
74 static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
75                              u8 *respData, size_t respDataLen)
76 {
77         const u8 *pos;
78         size_t len;
79
80         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
81                                respData, respDataLen, &len);
82         if (pos == NULL || len < 1) {
83                 wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
84                 return TRUE;
85         }
86
87         return FALSE;
88 }
89
90
91 static void eap_gtc_process(struct eap_sm *sm, void *priv,
92                             u8 *respData, size_t respDataLen)
93 {
94         struct eap_gtc_data *data = priv;
95         const u8 *pos;
96         size_t rlen;
97
98         if (sm->user == NULL || sm->user->password == NULL ||
99             sm->user->password_hash) {
100                 wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not "
101                            "configured");
102                 data->state = FAILURE;
103                 return;
104         }
105
106         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
107                                respData, respDataLen, &rlen);
108         if (pos == NULL || rlen < 1)
109                 return; /* Should not happen - frame already validated */
110
111         wpa_hexdump_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
112
113         if (rlen != sm->user->password_len ||
114             memcmp(pos, sm->user->password, rlen) != 0) {
115                 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
116                 data->state = FAILURE;
117         } else {
118                 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success");
119                 data->state = SUCCESS;
120         }
121 }
122
123
124 static Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv)
125 {
126         struct eap_gtc_data *data = priv;
127         return data->state != CONTINUE;
128 }
129
130
131 static Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv)
132 {
133         struct eap_gtc_data *data = priv;
134         return data->state == SUCCESS;
135 }
136
137
138 int eap_server_gtc_register(void)
139 {
140         struct eap_method *eap;
141         int ret;
142
143         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
144                                       EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
145         if (eap == NULL)
146                 return -1;
147
148         eap->init = eap_gtc_init;
149         eap->reset = eap_gtc_reset;
150         eap->buildReq = eap_gtc_buildReq;
151         eap->check = eap_gtc_check;
152         eap->process = eap_gtc_process;
153         eap->isDone = eap_gtc_isDone;
154         eap->isSuccess = eap_gtc_isSuccess;
155
156         ret = eap_server_method_register(eap);
157         if (ret)
158                 eap_server_method_free(eap);
159         return ret;
160 }