~ubuntu-branches/ubuntu/natty/hostapd/natty-updates

« back to all changes in this revision

Viewing changes to eap_vendor_test.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2009-04-03 07:07:06 UTC
  • mfrom: (1.1.11 upstream) (4.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090403070706-g8oc44qjhbixs4uf
Tags: 1:0.6.9-2
Enable CONFIG_IEEE80211W, IEEE 802.11w (management frame
protection). (Closes: #522328)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * hostapd / Test method for vendor specific (expanded) EAP type
3
 
 * Copyright (c) 2005, 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
 
#define EAP_VENDOR_ID 0xfffefd
23
 
#define EAP_VENDOR_TYPE 0xfcfbfaf9
24
 
 
25
 
 
26
 
struct eap_vendor_test_data {
27
 
        enum { INIT, CONFIRM, SUCCESS, FAILURE } state;
28
 
};
29
 
 
30
 
 
31
 
static const char * eap_vendor_test_state_txt(int state)
32
 
{
33
 
        switch (state) {
34
 
        case INIT:
35
 
                return "INIT";
36
 
        case CONFIRM:
37
 
                return "CONFIRM";
38
 
        case SUCCESS:
39
 
                return "SUCCESS";
40
 
        case FAILURE:
41
 
                return "FAILURE";
42
 
        default:
43
 
                return "?";
44
 
        }
45
 
}
46
 
 
47
 
 
48
 
static void eap_vendor_test_state(struct eap_vendor_test_data *data,
49
 
                                  int state)
50
 
{
51
 
        wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s",
52
 
                   eap_vendor_test_state_txt(data->state),
53
 
                   eap_vendor_test_state_txt(state));
54
 
        data->state = state;
55
 
}
56
 
 
57
 
 
58
 
static void * eap_vendor_test_init(struct eap_sm *sm)
59
 
{
60
 
        struct eap_vendor_test_data *data;
61
 
 
62
 
        data = wpa_zalloc(sizeof(*data));
63
 
        if (data == NULL)
64
 
                return NULL;
65
 
        data->state = INIT;
66
 
 
67
 
        return data;
68
 
}
69
 
 
70
 
 
71
 
static void eap_vendor_test_reset(struct eap_sm *sm, void *priv)
72
 
{
73
 
        struct eap_vendor_test_data *data = priv;
74
 
        free(data);
75
 
}
76
 
 
77
 
 
78
 
static u8 * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, int id,
79
 
                                     size_t *reqDataLen)
80
 
{
81
 
        struct eap_vendor_test_data *data = priv;
82
 
        struct eap_hdr *req;
83
 
        u8 *pos;
84
 
 
85
 
        *reqDataLen = sizeof(*req) + 8 + 1;
86
 
        req = malloc(*reqDataLen);
87
 
        if (req == NULL) {
88
 
                wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate "
89
 
                           "memory for request");
90
 
                return NULL;
91
 
        }
92
 
 
93
 
        req->code = EAP_CODE_REQUEST;
94
 
        req->identifier = id;
95
 
        req->length = htons(*reqDataLen);
96
 
        pos = (u8 *) (req + 1);
97
 
        *pos++ = EAP_TYPE_EXPANDED;
98
 
        WPA_PUT_BE24(pos, EAP_VENDOR_ID);
99
 
        pos += 3;
100
 
        WPA_PUT_BE32(pos, EAP_VENDOR_TYPE);
101
 
        pos += 4;
102
 
        *pos = data->state == INIT ? 1 : 3;
103
 
 
104
 
        return (u8 *) req;
105
 
}
106
 
 
107
 
 
108
 
static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv,
109
 
                                     u8 *respData, size_t respDataLen)
110
 
{
111
 
        struct eap_hdr *resp;
112
 
        u8 *pos;
113
 
        size_t len;
114
 
        int vendor;
115
 
        u32 method;
116
 
 
117
 
        resp = (struct eap_hdr *) respData;
118
 
        pos = (u8 *) (resp + 1);
119
 
        if (respDataLen < sizeof(*resp))
120
 
                return TRUE;
121
 
        len = ntohs(resp->length);
122
 
        if (len > respDataLen)
123
 
                return TRUE;
124
 
 
125
 
        if (len < sizeof(*resp) + 8 || *pos != EAP_TYPE_EXPANDED) {
126
 
                wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame");
127
 
                return TRUE;
128
 
        }
129
 
        pos++;
130
 
 
131
 
        vendor = WPA_GET_BE24(pos);
132
 
        pos += 3;
133
 
        method = WPA_GET_BE32(pos);
134
 
        pos++;
135
 
 
136
 
        if (vendor != EAP_VENDOR_ID || method != EAP_VENDOR_TYPE)
137
 
                return TRUE;
138
 
 
139
 
        return FALSE;
140
 
}
141
 
 
142
 
 
143
 
static void eap_vendor_test_process(struct eap_sm *sm, void *priv,
144
 
                                    u8 *respData, size_t respDataLen)
145
 
{
146
 
        struct eap_vendor_test_data *data = priv;
147
 
        struct eap_hdr *resp;
148
 
        u8 *pos;
149
 
 
150
 
        resp = (struct eap_hdr *) respData;
151
 
        pos = (u8 *) (resp + 1);
152
 
        pos += 8; /* Skip expanded header */
153
 
 
154
 
        if (data->state == INIT) {
155
 
                if (*pos == 2)
156
 
                        eap_vendor_test_state(data, CONFIRM);
157
 
                else
158
 
                        eap_vendor_test_state(data, FAILURE);
159
 
        } else if (data->state == CONFIRM) {
160
 
                if (*pos == 4)
161
 
                        eap_vendor_test_state(data, SUCCESS);
162
 
                else
163
 
                        eap_vendor_test_state(data, FAILURE);
164
 
        } else
165
 
                eap_vendor_test_state(data, FAILURE);
166
 
}
167
 
 
168
 
 
169
 
static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv)
170
 
{
171
 
        struct eap_vendor_test_data *data = priv;
172
 
        return data->state == SUCCESS;
173
 
}
174
 
 
175
 
 
176
 
static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
177
 
{
178
 
        struct eap_vendor_test_data *data = priv;
179
 
        u8 *key;
180
 
        const int key_len = 64;
181
 
 
182
 
        if (data->state != SUCCESS)
183
 
                return NULL;
184
 
 
185
 
        key = malloc(key_len);
186
 
        if (key == NULL)
187
 
                return NULL;
188
 
 
189
 
        memset(key, 0x11, key_len / 2);
190
 
        memset(key + key_len / 2, 0x22, key_len / 2);
191
 
        *len = key_len;
192
 
 
193
 
        return key;
194
 
}
195
 
 
196
 
 
197
 
static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv)
198
 
{
199
 
        struct eap_vendor_test_data *data = priv;
200
 
        return data->state == SUCCESS;
201
 
}
202
 
 
203
 
 
204
 
int eap_server_vendor_test_register(void)
205
 
{
206
 
        struct eap_method *eap;
207
 
        int ret;
208
 
 
209
 
        eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
210
 
                                      EAP_VENDOR_ID, EAP_VENDOR_TYPE,
211
 
                                      "VENDOR-TEST");
212
 
        if (eap == NULL)
213
 
                return -1;
214
 
 
215
 
        eap->init = eap_vendor_test_init;
216
 
        eap->reset = eap_vendor_test_reset;
217
 
        eap->buildReq = eap_vendor_test_buildReq;
218
 
        eap->check = eap_vendor_test_check;
219
 
        eap->process = eap_vendor_test_process;
220
 
        eap->isDone = eap_vendor_test_isDone;
221
 
        eap->getKey = eap_vendor_test_getKey;
222
 
        eap->isSuccess = eap_vendor_test_isSuccess;
223
 
 
224
 
        ret = eap_server_method_register(eap);
225
 
        if (ret)
226
 
                eap_server_method_free(eap);
227
 
        return ret;
228
 
}