~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/eap_server/eap_server_gtc.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "common.h"
 
18
#include "eap_i.h"
 
19
 
 
20
 
 
21
struct eap_gtc_data {
 
22
        enum { CONTINUE, SUCCESS, FAILURE } state;
 
23
        int prefix;
 
24
};
 
25
 
 
26
 
 
27
static void * eap_gtc_init(struct eap_sm *sm)
 
28
{
 
29
        struct eap_gtc_data *data;
 
30
 
 
31
        data = os_zalloc(sizeof(*data));
 
32
        if (data == NULL)
 
33
                return NULL;
 
34
        data->state = CONTINUE;
 
35
 
 
36
#ifdef EAP_SERVER_FAST
 
37
        if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
 
38
            sm->m->method == EAP_TYPE_FAST) {
 
39
                wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
 
40
                           "with challenge/response");
 
41
                data->prefix = 1;
 
42
        }
 
43
#endif /* EAP_SERVER_FAST */
 
44
 
 
45
        return data;
 
46
}
 
47
 
 
48
 
 
49
static void eap_gtc_reset(struct eap_sm *sm, void *priv)
 
50
{
 
51
        struct eap_gtc_data *data = priv;
 
52
        os_free(data);
 
53
}
 
54
 
 
55
 
 
56
static struct wpabuf * eap_gtc_buildReq(struct eap_sm *sm, void *priv, u8 id)
 
57
{
 
58
        struct eap_gtc_data *data = priv;
 
59
        struct wpabuf *req;
 
60
        char *msg;
 
61
        size_t msg_len;
 
62
 
 
63
        msg = data->prefix ? "CHALLENGE=Password" : "Password";
 
64
 
 
65
        msg_len = os_strlen(msg);
 
66
        req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, msg_len,
 
67
                            EAP_CODE_REQUEST, id);
 
68
        if (req == NULL) {
 
69
                wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for "
 
70
                           "request");
 
71
                data->state = FAILURE;
 
72
                return NULL;
 
73
        }
 
74
 
 
75
        wpabuf_put_data(req, msg, msg_len);
 
76
 
 
77
        data->state = CONTINUE;
 
78
 
 
79
        return req;
 
80
}
 
81
 
 
82
 
 
83
static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
 
84
                             struct wpabuf *respData)
 
85
{
 
86
        const u8 *pos;
 
87
        size_t len;
 
88
 
 
89
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &len);
 
90
        if (pos == NULL || len < 1) {
 
91
                wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
 
92
                return TRUE;
 
93
        }
 
94
 
 
95
        return FALSE;
 
96
}
 
97
 
 
98
 
 
99
static void eap_gtc_process(struct eap_sm *sm, void *priv,
 
100
                            struct wpabuf *respData)
 
101
{
 
102
        struct eap_gtc_data *data = priv;
 
103
        const u8 *pos;
 
104
        size_t rlen;
 
105
 
 
106
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &rlen);
 
107
        if (pos == NULL || rlen < 1)
 
108
                return; /* Should not happen - frame already validated */
 
109
 
 
110
        wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
 
111
 
 
112
#ifdef EAP_SERVER_FAST
 
113
        if (data->prefix) {
 
114
                const u8 *pos2, *end;
 
115
                /* "RESPONSE=<user>\0<password>" */
 
116
                if (rlen < 10) {
 
117
                        wpa_printf(MSG_DEBUG, "EAP-GTC: Too short response "
 
118
                                   "for EAP-FAST prefix");
 
119
                        data->state = FAILURE;
 
120
                        return;
 
121
                }
 
122
 
 
123
                end = pos + rlen;
 
124
                pos += 9;
 
125
                pos2 = pos;
 
126
                while (pos2 < end && *pos2)
 
127
                        pos2++;
 
128
                if (pos2 == end) {
 
129
                        wpa_printf(MSG_DEBUG, "EAP-GTC: No password in "
 
130
                                   "response to EAP-FAST prefix");
 
131
                        data->state = FAILURE;
 
132
                        return;
 
133
                }
 
134
 
 
135
                wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Response user",
 
136
                                  pos, pos2 - pos);
 
137
                if (sm->identity && sm->require_identity_match &&
 
138
                    (pos2 - pos != (int) sm->identity_len ||
 
139
                     os_memcmp(pos, sm->identity, sm->identity_len))) {
 
140
                        wpa_printf(MSG_DEBUG, "EAP-GTC: Phase 2 Identity did "
 
141
                                   "not match with required Identity");
 
142
                        wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Expected "
 
143
                                          "identity",
 
144
                                          sm->identity, sm->identity_len);
 
145
                        data->state = FAILURE;
 
146
                        return;
 
147
                } else {
 
148
                        os_free(sm->identity);
 
149
                        sm->identity_len = pos2 - pos;
 
150
                        sm->identity = os_malloc(sm->identity_len);
 
151
                        if (sm->identity == NULL) {
 
152
                                data->state = FAILURE;
 
153
                                return;
 
154
                        }
 
155
                        os_memcpy(sm->identity, pos, sm->identity_len);
 
156
                }
 
157
 
 
158
                if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
 
159
                        wpa_hexdump_ascii(MSG_DEBUG, "EAP-GTC: Phase2 "
 
160
                                          "Identity not found in the user "
 
161
                                          "database",
 
162
                                          sm->identity, sm->identity_len);
 
163
                        data->state = FAILURE;
 
164
                        return;
 
165
                }
 
166
 
 
167
                pos = pos2 + 1;
 
168
                rlen = end - pos;
 
169
                wpa_hexdump_ascii_key(MSG_MSGDUMP,
 
170
                                      "EAP-GTC: Response password",
 
171
                                      pos, rlen);
 
172
        }
 
173
#endif /* EAP_SERVER_FAST */
 
174
 
 
175
        if (sm->user == NULL || sm->user->password == NULL ||
 
176
            sm->user->password_hash) {
 
177
                wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not "
 
178
                           "configured");
 
179
                data->state = FAILURE;
 
180
                return;
 
181
        }
 
182
 
 
183
        if (rlen != sm->user->password_len ||
 
184
            os_memcmp(pos, sm->user->password, rlen) != 0) {
 
185
                wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
 
186
                data->state = FAILURE;
 
187
        } else {
 
188
                wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success");
 
189
                data->state = SUCCESS;
 
190
        }
 
191
}
 
192
 
 
193
 
 
194
static Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv)
 
195
{
 
196
        struct eap_gtc_data *data = priv;
 
197
        return data->state != CONTINUE;
 
198
}
 
199
 
 
200
 
 
201
static Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv)
 
202
{
 
203
        struct eap_gtc_data *data = priv;
 
204
        return data->state == SUCCESS;
 
205
}
 
206
 
 
207
 
 
208
int eap_server_gtc_register(void)
 
209
{
 
210
        struct eap_method *eap;
 
211
        int ret;
 
212
 
 
213
        eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
 
214
                                      EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
 
215
        if (eap == NULL)
 
216
                return -1;
 
217
 
 
218
        eap->init = eap_gtc_init;
 
219
        eap->reset = eap_gtc_reset;
 
220
        eap->buildReq = eap_gtc_buildReq;
 
221
        eap->check = eap_gtc_check;
 
222
        eap->process = eap_gtc_process;
 
223
        eap->isDone = eap_gtc_isDone;
 
224
        eap->isSuccess = eap_gtc_isSuccess;
 
225
 
 
226
        ret = eap_server_method_register(eap);
 
227
        if (ret)
 
228
                eap_server_method_free(eap);
 
229
        return ret;
 
230
}