2
* EAP peer method: EAP-TNC (Trusted Network Connect)
3
* Copyright (c) 2007, 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.
25
struct tncc_data *tncc;
30
#define EAP_TNC_FLAGS_LENGTH_INCLUDED 0x80
31
#define EAP_TNC_FLAGS_MORE_FRAGMENTS 0x40
32
#define EAP_TNC_FLAGS_START 0x20
33
#define EAP_TNC_VERSION_MASK 0x07
35
#define EAP_TNC_VERSION 1
38
static void * eap_tnc_init(struct eap_sm *sm)
40
struct eap_tnc_data *data;
42
data = os_zalloc(sizeof(*data));
45
data->state = METHOD_INIT;
46
data->tncc = tncc_init();
47
if (data->tncc == NULL) {
56
static void eap_tnc_deinit(struct eap_sm *sm, void *priv)
58
struct eap_tnc_data *data = priv;
60
tncc_deinit(data->tncc);
65
static u8 * eap_tnc_process(struct eap_sm *sm, void *priv,
66
struct eap_method_ret *ret,
67
const u8 *reqData, size_t reqDataLen,
70
struct eap_tnc_data *data = priv;
71
const struct eap_hdr *req;
77
char *start_buf, *end_buf;
78
size_t start_len, end_len;
80
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TNC,
81
reqData, reqDataLen, &len);
82
if (pos == NULL || len == 0) {
83
wpa_printf(MSG_INFO, "EAP-TNC: Invalid frame (pos=%p len=%lu)",
84
pos, (unsigned long) len);
89
req = (const struct eap_hdr *) reqData;
90
wpa_hexdump(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
91
wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
93
if ((*pos & EAP_TNC_VERSION_MASK) != EAP_TNC_VERSION) {
94
wpa_printf(MSG_DEBUG, "EAP-TNC: Unsupported version %d",
95
*pos & EAP_TNC_VERSION_MASK);
100
if (data->state == METHOD_INIT) {
101
if (!(*pos & EAP_TNC_FLAGS_START)) {
102
wpa_printf(MSG_DEBUG, "EAP-TNC: Server did not use "
103
"start flag in the first message");
108
tncc_init_connection(data->tncc);
110
data->state = METHOD_MAY_CONT;
112
if (*pos & EAP_TNC_FLAGS_START) {
113
wpa_printf(MSG_DEBUG, "EAP-TNC: Server used start "
119
if (tncc_process_if_tnccs(data->tncc, pos + 1, len - 1)) {
126
ret->methodState = data->state;
127
ret->decision = DECISION_UNCOND_SUCC;
128
ret->allowNotifications = TRUE;
130
imc_len = tncc_total_send_len(data->tncc);
132
start_buf = tncc_if_tnccs_start(data->tncc);
133
if (start_buf == NULL)
135
start_len = os_strlen(start_buf);
136
end_buf = tncc_if_tnccs_end();
137
if (end_buf == NULL) {
141
end_len = os_strlen(end_buf);
143
rlen = 1 + start_len + imc_len + end_len;
144
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, respDataLen,
145
rlen, EAP_CODE_RESPONSE,
146
req->identifier, &rpos);
154
*rpos++ = EAP_TNC_VERSION;
155
os_memcpy(rpos, start_buf, start_len);
159
rpos = tncc_copy_send_buf(data->tncc, rpos);
161
os_memcpy(rpos, end_buf, end_len);
164
wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Response", start, rlen);
170
int eap_peer_tnc_register(void)
172
struct eap_method *eap;
175
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
176
EAP_VENDOR_IETF, EAP_TYPE_TNC, "TNC");
180
eap->init = eap_tnc_init;
181
eap->deinit = eap_tnc_deinit;
182
eap->process = eap_tnc_process;
184
ret = eap_peer_method_register(eap);
186
eap_peer_method_free(eap);